git push.default=current和push.default=upstream之间有什么区别?

94
git-config的man页面列出了push.default的这些选项:
nothing - do not push anything.
matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default.
upstream - push the current branch to its upstream branch.
tracking - deprecated synonym for upstream.
current - push the current branch to a branch of the same name.

在大多数情况下,我会认为将代码推送到一个分支的上游分支与推送到同名分支是一样的,因为上游分支通常会有相同的名称,并且同名的分支(“current”)通常(或者根据定义总是?)是上游的。那么有什么区别呢?
更新:git-config的文档已经更新(正如人们所期望的那样),所以现在可能会更清楚地解释其中的区别。

2
对于开发人员来说,区分这些确实很烦人,因此引入了“简单”模式,并将成为git-push的默认行为。实际上,它出现在[git 1.7.11](https://raw.github.com/git/git/master/Documentation/RelNotes/1.7.11.txt)中。 - xhlwill
15
有关最近的git警告“push.default未设置;其隐式值在Git 2.0中正在更改”以及关于“matching”与“simple”的更多信息,请参见http://stackoverflow.com /questions/13148066/warning-push-default-is-unset-its-implicit-value-is-changing-in-git-2-0 - Nate
iconoclaust:我认为我的编辑完全没有改变问题的完整性,过时的信息只需要修复。为什么要让用户多做一些点击链接的额外工作呢? - Flimm
2个回答

77
您已经在问题中总结了它们之间的区别。 upstream 推送到配置的上游分支,而 current 假定上游分支的名称与当前的本地分支相同,并推送到该特定名称。实际情况是,没有理由假设本地分支的上游跟踪分支与本地分支本身具有相同的名称。
例如,如果您在多个存储库或许多共享的开发人员远程中工作,则通常会跟踪同一分支的不同分支,例如 allen-mastersusan-master,它们都分别跟踪 Allen 和 Susan 存储库中的 master 分支。在这种情况下,current 将是不正确的设置,因为这些分支名称不存在于它们的远程上。然而,upstream 将完全正常工作。
一个更实际的例子可能是同时跟踪 developmentproduction 存储库。您的工作流程可能对每个存储库使用不同的主线分支,但那可能会令人困惑。假设您是代码集成器,并想要分别跟踪两个存储库的 master 分支。
git checkout -b production --track production/master
git checkout -b development --track development/master
现在你有两个跟踪各自仓库的分支,它们都没有使用master命名约定。分支名称非常明确地描述了它们所跟踪的内容,因此没有关于分支名称的混淆。然而,由于远程仓库都没有development或production分支,因此push.default = current没有任何意义。

6
您需要两个例子说明何时应该使用“上游(upstream)”而不是“当前(current)”。我认为这很明显,所以您应该给出相反情况的例子。 - AndreKR
2
据我所知,如果你是一个相对新手的开发者,current会更好一些,因为你不需要太多的git config操作,特别是如果你是从其他地方克隆来的。如果同名分支不存在,则current将为你推送到远程仓库上的同名分支或者创建一个同名分支并将其推送到远程仓库上。相反,当同名分支不存在时,simple将直接拒绝执行此操作。在这种情况下,除非已经设置了上游分支或者按照 Yawar 的回答中提到的那样进行了设置,upstream的行为与simple相同。 - Seldom 'Where's Monica' Needy
实际上,没有理由假设本地分支的上游跟踪分支与本地分支本身具有相同的名称。这取决于您团队的Git策略。我知道一些大公司由于公司政策而禁止分叉,即使他们有一个庞大的开发团队。在这种情况下,只需使用“current”。 - superarts.org

7
current会将当前分支推送到远程仓库上同名的分支。 upstream会将当前分支推送到上游分支。
上游分支是一个已经被明确或者隐式定义为是你当前分支上游的分支。这意味着默认情况下,推送和拉取操作将与该分支同步。上游分支可能与当前分支本身在同一仓库中。你可以设置你的本地主分支作为你的本地特性(主题)分支的上游分支,并在它们之间进行推送和拉取等有趣的操作。
隐式的上游设置是通过branch.autosetupmerge配置值来完成的。你可以在git config帮助页面中找到文档。显式的上游设置是通过-u选项添加到git branch命令中完成的。有关详细信息,请参见帮助页面。

我认为branch.autoSetupMerge-u/--set-upstream不是同一件事。至少,在文档中没有任何暗示表明它会使git push默认行为像使用-u一样,这似乎是你所说的。你能澄清一下你的意思吗? - waldyrious
@waldyrious 当你检查远程跟踪分支时,默认情况下,branch.autoSetupMerge 配置会创建一个新的本地分支,并将其上游设置为远程跟踪分支。这个隐式操作可以通过使用 -t (--track) 或 -u ... (--set-upstream-to=...) 标志来显式执行,它们使用略有不同的语法来完成相同的操作。 - Yawar
2
我看到这里发生了什么——由于这个问题涉及git push,我(错误地)假设你在谈论git push-u选项,而不是git branch-u选项。对于造成的困惑表示抱歉 :) - waldyrious

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