我有一个关于git的问题...假设我用这段代码克隆了我的项目
git clone ssh://git@<my-project.git>
然后执行类似下面的行来添加远程上行链路
git remote add upstream ssh://git@<my-project.git>
当我尝试运行此行时,我已经验证了我的上游已设置
$ git remote -v
origin ssh://git@<my-project.git> (fetch)
origin ssh://git@<my-project.git> (push)
upstream ssh://git@<my-project.git> (fetch)
upstream ssh://git@<my-project.git> (push)
所以我创建了一个新的分支
git checkout -b sample-branch master
Switched to a new branch 'sample-branch'
但当我试图推动我的本地分支,我得到低于错误.
git push
fatal: The current branch sample-branch has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin sample-branch
可能我想既然我已经添加了一个上游,那么我的本地分支就不需要设置我的上游了,或者我想错了,我必须先执行上面的行,然后才能执行
git push
根据后续命令。
3条答案
按热度按时间hgncfbus1#
有关TL; DR版本,请参见VonC's answer。
git remote add
添加了一个 * remote *。remote可以有任何你喜欢的名字,尽管按照惯例,origin
是第一个,upstream
通常是第二个。但是通常如果你添加了第二个remote,它会有一个 * 不同的 * URL,而不是相同的URL。如果你与多个不同的Git仓库通信,每个仓库在不同的URL,你只需要多个remote。令人困惑的是,名为
upstream
的远程(假设您有一个)不是上游,它只是一个远程。术语 * upstream * 用于分支名称时,指的是内部的两部分设置(如VonC said)。每个分支名称(如
master
或feature
)都可以有一个上游,典型地,master
的上游将是origin/master
,并且feature
的上游将是origin/feature
。如果您确实有多个远程,并且调用了第二个远程upstream
,则可以将branchX
的上游设置为upstream/branchX
。所以:分支的 * upstream * 是其他的名字,通常以 * remote * 开头。Git使用这个设置来记住"我从那里获取/拉取"和"我从那里推送"。这个名字 * 必须实际存在 *,这才是真正令人困惑的地方。
所以我创建了一个新的分支
从技术上讲,这会在您自己的Git仓库中创建一个新的分支名称
sample-branch
,这个新分支名称所选择的提交哈希ID与现有名称master
(也是一个分支名称)所选择的提交哈希ID相同。当你使用这种
git checkout
命令时,你的Git会将新分支的上游设置为另一个分支的 * name , 如果 * 它是origin/sample-branch
的话。但是你可能 * 没有 *origin/sample-branch
。这个名字只有当Git位于origin
时才会存在--位于存储在 * remote * 中的名为origin
的URL,也就是说,有一个名为sample-branch
的分支,你的Git看到了这个分支并复制了它。因为你没有在这里使用origin/sample-branch
--即使你使用了,它也会失败--你的Git * 没有 * 为新分支设置上游。你最终需要做一些事情。没有必要马上做!你可以随时做。但最终,你确实需要做。有两个步骤:
1.你必须得到另一个Git,
origin
上的那个,来创建一个名为sample-branch
的分支。当你得到那个Git来创建它的sample-branch
时,你的Git就可以把它复制到你的origin/sample-branch
上,这样你的origin/sample-branch
就存在了。1.一旦你的
origin/sample-branch
存在,你需要得到 * 你的 * Git来设置origin/sample-branch
作为sample-branch
的上游。你可以用两个独立的Git命令来完成这两个步骤,在古代,你必须这样做,而在现代的Git版本中,一个命令就足够了,那就是
git push -u origin sample-branch
。它的作用是:
1.让您的Git使用存储在名称
origin
中的URL调用他们的Git(位于origin
的Git)。你的Git会向他们的Git提供完成整个任务所需的任何新提交和其他对象。如果需要,你的Git会向他们发送提交及其包含的文件。一旦他们得到了所需的一切,你的Git会向他们发送一个礼貌的请求:* 如果可以的话,请创建或更新您的名字
sample-branch
,以便它能标识一个特定的提交。* 您的Git在这里推荐的特定提交与 * 您的 * 名字sample-branch
标识的提交相同。如果他们接受这个请求,就会创建他们的
sample-branch
。由于你的Git现在看到他们的Git有sample-branch
,你的Git会创建你的origin/sample-branch
来记住这一点。1.现在你的Git有了
origin/sample-branch
,你的git push -u
会自动调用git branch --set-upstream-to=origin/sample-branch sample-branch
。如果您出于某种原因希望按照以前的两步方法执行此操作,请运行:
(the两个名字之间用冒号隔开,告诉你的Git应该告诉他们什么)。然后,当这个成功的时候,运行:
显然,单个
git push -u
命令更短、更容易。qybjjes12#
设置上游远程不同于设置上游分支(上游分支是远程+远程分支名称):你的第二个遥控器应该根本不需要。
请参见"Upstream (as related to) Tracking"。
先试一下:
则
git branch -avv
:你会看到你的分支与一个远程分支相关联。git push
将用于下一次提交发布。gcuhipw93#
现有的两个答案变成了很多理论,为什么 * 默认情况下 *,你需要做这另一件事,因为你的问题暗示了对上游远程分支和本地分支的上游跟踪分支之间的区别缺乏理解。
然而,在我看来,对你的问题更简短/更好的回答是你不应该需要。
如果你运行的是git 2.37+,并且运行了以下命令,git会按照你和我的大多数人的预期运行:
当您使用与远程分支相同的名称进行本地分支时,现有的远程上游将被设置为跟踪分支,并且
git pull
和git push
将如您所期望的那样工作(就像它们现在所做的那样)。当您使用一个 * 不同 * 的名称进行本地分支时,最初将不设置跟踪分支-
git pull
还不会工作。当您第一次使用git push
时,您正在推送的新远程分支将被设置为您的新远程跟踪分支,并且git pull
和git push
将按照您的预期工作-推送到/拉入到您在第一次“推送”中创建的远程分支。我不知道这些配置选项是否会成为默认值,但在我看来,它们可以避免大部分git用户的恐慌,尤其是当他们开始使用它的时候。