为什么需要第二个跟踪分支来作为原点/主记录 [英] why need a second tracking branch for origin/master
问题描述
我正在阅读Pro Git书,并为原点/母版设置了第二个跟踪分支而感到困惑.以下是这本书的描述:
...例如,如果您想向项目提交第二个工作主题,则不要继续处理刚刚推入的主题分支-从主存储库的master分支重新开始:
$git checkout -b featureB origin/master
...work
$git commit
$git push myfork featureB
$git fetch origin
因此,提交历史记录如下图所示:
Q1-master分支已经在跟踪原始/母版,为什么作者创建了第二个分支-featureB来跟踪原始/母版?这样做有什么好处?
TL; DR
在这里实际上没有用.这只是某些有用的副作用.
长
这里有一个术语问题.具体来说,单词 track 或 tracking 以及短语 tracking branch 或 branch is tracking 都是模棱两可且容易实现的滥用随着时间的流逝,Git文档已经从动词 tracking 的使用转向使用名词或形容词 upstream 的使用.让我们尝试改用这个词,以免造成混淆.
一个分支名称,例如master
或featureA
或featureB
,可以没有上游,也可以有一个上游. (这是仅有的两个选项.)因此,featureA
的上游是 set 或 unset .如果已设置,则featureA
的上游要么是您的另一个分支名称(例如master
),要么是您的远程跟踪名称 1 之一.为origin/master
或origin/featureA
.
使用时:
git checkout -b featureA origin/master
您创建一个新的分支名称featureA
.如果您这样做:
git checkout origin/master
git checkout -b featureA
新分支名称featureA
将在上游没有 :它将不会跟踪任何内容.或者,如果您已这样做:
git checkout -b featureA master
这同样适用,尽管如果origin/master
和master
标识不同的 commits ,那么您现在将处于不同的提交.但是使用时:
git checkout -b featureA origin/master
Git可能(实际上是默认值)会将新分支featureA
的上游设置为origin/master
.这取决于branch.autoSetupMerge
的设置(默认为true
).如果branch.autoSetupMerge
是true
(或未设置),则使用一些现有的远程跟踪名称(例如origin/master
)作为起点创建新分支,将导致git checkout
和git branch
设置指定的远程跟踪名称为新分支的上游.
将featureA
的上游设置为origin/master
通常没有用,甚至可能是不希望的.如果您不希望这种上游设置发生,则可以使用三个直接选项(以及更多间接选项,例如上面概述的多步方法):
-
更改
branch.autoSetupMerge
的设置.这会影响以后的所有git checkout -b
操作,这些操作(1)省略--track
或--no-track
,以及(2)使用远程跟踪名称作为新分支名称的起始提交.您可以使用git -c
暂时将其设置为一个命令:git -c branch.autoSetupMerge=false checkout -b featureA origin/master
但是由于下一个选项,这毫无意义.
-
使用
git checkout -b --no-track featureA origin/master
覆盖默认值.新分支featureA
将没有上游. -
允许
featureA
短暂地提供错误的上游,然后手动对其进行修复.例如,在本地创建featureA
后,您可能希望立即在origin
的Git中创建featureA
,并将featureA
的上游设置为新创建的origin/featureA
:git checkout -b featureA origin/master git push --set-upstream origin featureA
或者,使用
git branch --unset-upstream
:git checkout -b featureA origin/master git branch --unset-upstream featureA
(尽管在结帐命令中添加
--no-track
可能更简单).
拥有上游并不特别有害,因此将origin/master
设置为featureA
的上游一段时间可能是可以的.如果您不希望发生这种情况,请考虑上述各种选项.将Git命令视为工具而不是解决方案:它们会执行它们的工作,并且如果它们与您想要的工作保持一致,请使用它们.如果没有,请使用其他工具或有缺陷的工具,并通过修复操作对这些用途进行跟踪,以纠正缺陷.
1 Git称这些为远程跟踪分支名称,但我认为此处的 branch 词具有误导性,因此我宁愿忽略它.不幸的是,它仍然使用 remote 和 tracking 这两个词,而 remote 是Git中的另一个专业术语,但至少是连字符对 remote -tracking 与 remote 或 tracking 明显不同.
I'm reading the Pro Git book and got confused by setting up a second tracking branch for origin/master. Below is the description from the book:
...For example, if you want to submit a second topic of work to the project,don’t continue working on the topic branch you just pushed up — start over from the main repository’s master branch:
$git checkout -b featureB origin/master
...work
$git commit
$git push myfork featureB
$git fetch origin
so the commit history looks like the picture below:
Q1-master branch is already tracking origin/master, why the author created a second branch- featureB to track origin/master as well? What's the benefits of doing that?
TL;DR
It's not actually useful here. It's just a side effect of something that is sometimes useful.
Long
There is a terminology issue here. Specifically, the word track or tracking, and the phrase tracking branch or branch is tracking, is ambiguous and easy to misuse. The Git documentation has, over time, been moving away from the use of the verb tracking to, instead, use the noun-or-adjective upstream. Let's try to use this word instead, to help avoid confusion.
A branch name, such as master
or featureA
or featureB
, can have no upstream, or it can have one upstream. (These are the only two options.) Hence the upstream of featureA
is either set or unset. If it is set, the upstream of featureA
is either another of your branch names—such as master
—or is one of your remote-tracking names1 such as origin/master
or origin/featureA
.
When using:
git checkout -b featureA origin/master
you create a new branch name featureA
. If you had done this:
git checkout origin/master
git checkout -b featureA
the new branch name featureA
would have no upstream: it would not be tracking anything. Or, if you had done this:
git checkout -b featureA master
the same would hold, although if origin/master
and master
identify different commits, you'd now be on a different commit. But when using:
git checkout -b featureA origin/master
it's possible—and in fact the default—that Git will set the upstream of new branch featureA
to origin/master
. This depends on the setting of branch.autoSetupMerge
(which defaults to true
). If branch.autoSetupMerge
is true
(or unset), creating a new branch using some existing remote-tracking name (such as origin/master
) as its starting point causes git checkout
and git branch
to set the specified remote-tracking name as the upstream of the new branch.
Setting the upstream of featureA
to origin/master
is often not useful, and perhaps even undesired. If you don't want this upstream setting to happen, you have three direct options (plus more indirect options like the multi-step method outlined above):
Change the setting of
branch.autoSetupMerge
. This affects all futuregit checkout -b
operations that (1) omit either--track
or--no-track
and (2) use a remote-tracking name as the starting commit for the new branch name. You can set it temporarily for one command usinggit -c
:git -c branch.autoSetupMerge=false checkout -b featureA origin/master
but this is kind of pointless because of the next option.
Use
git checkout -b --no-track featureA origin/master
to override the default. The new branch,featureA
, will have no upstream.Allow
featureA
to have the wrong upstream briefly, but then manually fix it. For instance, having createdfeatureA
locally, you might want to createfeatureA
in the Git atorigin
immediately and set the upstream of yourfeatureA
to the newly-createdorigin/featureA
:git checkout -b featureA origin/master git push --set-upstream origin featureA
Or, use
git branch --unset-upstream
:git checkout -b featureA origin/master git branch --unset-upstream featureA
(although adding
--no-track
to your checkout command is probably simpler).
Having an upstream is not particularly harmful, so having origin/master
set as the upstream of featureA
for a while is probably OK. If you don't want it to happen, consider the various options above. Think of Git commands as tools rather than solutions: they do what they do, and if what they do aligns with what you want done, use them. If not, use other tools, or use the flawed tools and follow up those uses with fix-up operation to correct the flaws.
1Git calls these remote-tracking branch names, but I think the word branch here is misleading, so I prefer to omit it. This unfortunately still uses the words remote and tracking, and remote is another jargon word in Git, but at least the hyphenated pair remote-tracking is clearly slightly different from either remote or tracking.
这篇关于为什么需要第二个跟踪分支来作为原点/主记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!