为什么需要第二个跟踪分支来作为原点/主记录 [英] why need a second tracking branch for origin/master

查看:65
本文介绍了为什么需要第二个跟踪分支来作为原点/主记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读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 的使用.让我们尝试改用这个词,以免造成混淆.

一个分支名称,例如masterfeatureAfeatureB,可以没有上游,也可以有一个上游. (这是仅有的两个选项.)因此,featureA的上游是 set unset .如果已设置,则featureA的上游要么是您的另一个分支名称(例如master),要么是您的远程跟踪名称 1 之一.为origin/masterorigin/featureA.

使用时:

git checkout -b featureA origin/master

您创建一个新的分支名称featureA.如果您这样做:

git checkout origin/master
git checkout -b featureA

新分支名称featureA将在上游没有 :它将不会跟踪任何内容.或者,如果您已这样做:

git checkout -b featureA master

这同样适用,尽管如果origin/mastermaster标识不同的 commits ,那么您现在将处于不同的提交.但是使用时:

git checkout -b featureA origin/master

Git可能(实际上是默认值)会将新分支featureA的上游设置为origin/master.这取决于branch.autoSetupMerge的设置(默认为true).如果branch.autoSetupMergetrue(或未设置),则使用一些现有的远程跟踪名称(例如origin/master)作为起点创建新分支,将导致git checkoutgit 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 future git 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 using git -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 created featureA locally, you might want to create featureA in the Git at origin immediately and set the upstream of your featureA to the newly-created origin/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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆