git - 推送当前分支 vs 推送上游分支(跟踪)

38
我阅读了关于git push命令的文档,但我仍然不理解要在push.default中设置当前(current)上游(upstream)之间的确切区别。
我希望我们的团队只进行推送(push),并且只会推送他们正在工作的分支上所做的更改。 据我理解,这个分支是当我执行git branch命令时,标有*(星号)的那个分支。
谢谢您的帮助。
2个回答

56

问题是你正在推送{what},以及{to where}

  • current:

    • "what"仅为您当前的分支(没有其他分支),
    • "to where"是同名分支(如果不存在,则创建)在upstream repo中。
  • upstream:

    • "what"也仅为当前分支,
    • "to where"是将本地分支推送到上游库已指定为上游分支的任何分支(不一定是同名分支)。
根据在此解释, Git 2.0 还将引入一个新的默认选项 push.default: simple simple 类似于 upstream, 但是上游分支的名称必须相同,否则推送将失败。

只推送一个分支(使用模式“simple”,“current”或“upstream”)可以避免情况发生,即推送所有匹配的分支(模式“matching”,长期以来一直是默认值),尽管您的某些分支可能还没有准备好被推送。

(master)> git push
...
To git@github.com:jkubicek/my_proj.git
   21b430d..dd378ca  master -> master
 ! [rejected]        release -> release (non-fast-forward)
error: failed to push some refs to 'git@github.com:jkubicek/my_proj.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. 
hint: If you did not intend to push that branch, you may want to
hint: specify branches to push or set the 'push.default' configuration
hint: variable to 'current' or 'upstream' to push only the current branch.

两者之间的区别在于“pull”(从远程拉取到你的分支需要拉取什么内容):
- 推送“current”并不意味着您的当前分支B具有remote/B作为其上游分支。即:当您推送“current”分支时,branch.B.merge未设置。即:在将代码拉取到B时,Git不知道要拉取哪个分支。 - 推送“upstream”意味着您的当前分支B具有remote/B作为其上游分支。即:当您推送“upstream”分支时,branch.B.merge已经设置。即:在将代码拉取到B时,Git知道要拉取哪个分支(以及哪个远程仓库:branch.B.remote)。

1
push.defaultpull 没有影响!正确的说法是,上游分支的配置会影响拉取的内容。但两者(上游和 push.default)是完全不同的东西。 - Robert Siemer

7

push.default最好在git config的man页面中进行了解(man git-config)。

要了解push.default中“upstream”和“current”的区别,您应该了解术语“upstream”:

Upstream是普通本地分支到本地远程跟踪分支的本地指针。(是的,这些都是本地的。)例如:

  • 分支blabla具有origin/blabla配置为上游(非常常见)
  • 分支blabla具有origin/foo作为上游(分支具有不同的本地名称;不太常见)
  • 分支blabla具有origin2/foo作为上游

请注意,origin/*分支是本地的,并且在每次从原始位置获取时重新设置。这些称为“本地远程跟踪分支”。它们表示“origin”上一次获取时分支的状态。

每个(普通的)本地分支都可以配置一个上游,但这不是必须的:配置上游关系只是方便某些git命令的使用!

例如,如果执行了git status,git会告诉您“x个提交在上游/之前”,如果它知道上游(因此git可以与其进行比较)。

通常,正常的初始git checkout blabla会为您设置上游配置(如果存在origin/blabla,则将其检出并设置为上游-否则检查失败)。

git push也可以使用分支的上游配置,即将新提交内容复制到表示上游的远程分支。(这是push.default = upstream。)

push.default = currentgit push将新提交的内容复制到相同名称的远程分支下。它完全忽略上游配置。- 如果您的本地分支名称始终与远程分支名称相同,则两个配置具有相同的效果,除非使用push.default =upstreamgit push将失败,如果尚未配置上游。

PD:是的,在git branch的输出中*显示当前分支。


@ebelisle 这个 man 页面叫做 git-config,但是在我工作的系统上,也可以用 man git config 打开。你使用的是什么系统? - Robert Siemer
我正在使用macOS High Sierra,通过brew安装了git 2.20.1。 "man git-config" 对我有效,但是"man git config"只给我提供了git的手册页面。我们的情况可能有所不同。 - ebelisle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接