什么是跟踪分支?

有人能解释一下应用于git的“跟踪分支”吗?

下面是git-scm.com的定义:

Git中的“跟踪分支”是本地分支 与远程连接的分支 分支。当你用力拉它的时候 分支,它自动推和 拉到它所在的远端分支 与。< / p >

如果你总是从 相同的上游分支进入新的 布兰奇,如果你不想用

.

.

不幸的是,作为git的新手和来自SVN的新手,这个定义对我来说完全没有意义。

我正在阅读“Git实用指南”(顺便说一句,这是一本伟大的书),它们似乎表明跟踪分支是一件好事,在创建你的第一个远程(在这种情况下是起源)后,你应该将你的主分支设置为跟踪分支,但不幸的是,它不覆盖为什么跟踪分支是一件好事将主分支设置为原始存储库的跟踪分支有什么好处呢

有人能(用英语)给我开导一下吗?

172125 次浏览

ProGit书一个很好的解释:

跟踪分支

从远程分支签出本地分支会自动创建所谓的跟踪分支。跟踪分支是与远程分支有直接关系的本地分支。如果你在跟踪分支上并输入git push, Git会自动知道要推送到哪个服务器和哪个分支。同样,在其中一个分支上运行git pull会获取所有远程引用,然后自动在相应的远程分支中合并。

克隆存储库时,它通常会自动创建一个跟踪origin/master的主分支。这就是为什么git pushgit pull不带其他参数而开箱即用。但是,如果您愿意,您可以设置其他跟踪分支—不跟踪原点上的分支,也不跟踪主分支。简单的例子就是你刚才看到的运行git checkout -b [branch] [remotename]/[branch]的例子。如果你的Git版本是1.6.2或更高,你也可以使用--track简写:

$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"

要设置一个与远程分支名称不同的本地分支,您可以轻松地使用第一个版本的不同本地分支名称:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "sf"

现在,你的本地分支sf将自动推入和拉出origin/serverfix

额外的git status信息

有了跟踪分支,git status会告诉你你落后跟踪分支多远——这有助于提醒你还没有推送你的更改!它是这样的:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)

$ git status
On branch dev
Your branch and 'origin/dev' have diverged,
and have 3 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)


Pro Git书籍 提到:

跟踪分支是与远程分支有直接关系的本地分支

不完全是。SO问题“很难理解git-fetch"包括:

没有当地的跟踪分支的概念,只有远程跟踪分支。
所以origin/masterorigin repo中master的远程跟踪分支

注意,Git 2.37 (Q3 2022)允许你自动设置远程跟踪分支,使用:

git config --global push.autoSetupRemote true

但实际上,一旦你在以下两者之间建立了上游分支关系:

  • master这样的本地分支
  • 和像origin/master这样的远程跟踪分支

你可以用git branch -avv列出它们。

然后你可以将master视为本地跟踪分支:它跟踪远程跟踪分支机构 origin/master,而后者跟踪上游回购 origin的主分支。

alt text

换句话说:"remote"在“远程跟踪分支”;意味着远程分支的当地的拷贝(跟踪),以记住最后获取的内容。
作为迈克尔Freidgeim添加在评论中:

术语“远程跟踪分支”;是令人困惑的。

更准确的说法是:

位于本地的远程跟踪分支"。

否则,有人可能会解释为“远程跟踪分支”位于源服务器上。

这就是我如何添加一个跟踪分支,这样我就可以从它拉到我的新分支:

git branch --set-upstream-to origin/Development new-branch

以下是我个人关于GIT跟踪分支的学习笔记,希望对以后的访问者有所帮助:

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here < / p >


跟踪分支和“git取回”:

enter image description here enter image description here enter image description here < / p >

跟踪分支是一种节省我们打字的方法。它还在使用git statusgit branch -v时提供了一些额外的细节。

现在让我来解释一下我所说的“节省打字”是什么意思。

如果我们跟踪一个分支,我们不必总是键入git push origin <branch-name>git pull origin <branch-name>git fetch origin <branch-name>git merge origin <branch-name>git pull origin <branch-name>4,我们可以分别使用git pushgit pullgit fetchgit merge。如果我们不将remove命名为origin,我们可以分别使用git pull origin <branch-name>0, git pull origin <branch-name>1, git pull origin <branch-name>2,git pull origin <branch-name>3。

执行git pull的默认调用将等价于git fetch origin HEADgit merge HEAD,其中HEAD是指向当前分支的ref。

git push命令将当前分支上的所有提交发送到中央存储库。因此,该命令看起来像git push origin <current-branch>

如果我们在正在跟踪的分支上,那么git merge仅仅表示git merge origin/<current-branch>

我们跟踪一个分支,当我们:

  1. 使用git clone克隆一个存储库
  2. 使用git push -u origin <branch-name>。这个-u使它成为跟踪分支。
  3. 使用git branch -u origin/<branch-name> <branch-name>
  4. 在签出时使用--track。例git checkout --track origin/<branch-name>

博士TL;记住,所有的git 分支机构本身都是用于跟踪的一组历史文件。因此,每个分支实际上不都是“跟踪分支”吗?,因为这就是这些分支的用途:随着时间的推移跟踪文件的历史?

因此,我们可能应该称正常的git为“分支”,“跟踪分支”,但我们没有这样做。相反,我们把他们的名字缩短为“分支”。


所以这就是为什么“跟踪分支”这个术语;非常令人困惑:对于外行来说,它很容易意味着两种不同的东西。

在git中,术语“跟踪分支”;是更完整术语的简称:“remote -tracking-branch”;

如果一开始用更正式的术语代替,可能会更好,直到你对这些概念更熟悉为止。


让我们把你的问题改成这样:

什么是“Remote-tracking-branch”?

这里的关键词是“远程”,所以跳过你感到困惑的地方,我将描述什么是远程跟踪分支以及如何使用它。


为了更好地理解git术语,包括分支机构跟踪,这在一开始可能非常令人困惑,我认为如果你首先对git是什么它是如何工作的的基本结构非常清楚,这是最简单的。如果没有这样的扎实理解,我保证你会迷失在许多细节中,因为git非常复杂;(翻译:很多人用它来做非常重要的事情)。

下面是一个介绍/概述,但你可能会发现这篇精彩的文章也有丰富的信息。


git是什么,它是干什么用的

git存储库就像一个家庭相册:它保存历史快照,显示过去的事情是如何发生的。一个“snapshot"在某一特定时刻对某事的记录。

git存储库并不局限于保存人类家庭照片。它可以是用于记录和组织任何随着时间发展或变化的东西

基本的想法是创造一本书,这样我们就可以很容易地回顾过去,

  • 比较过去的时间,与现在,或其他时刻的时间,和
  • 重现过去。

当您陷入复杂性和术语的泥潭时,试着记住一个git存储库是首要的,一个快照存储库,就像相册一样,它用于存储和组织这些快照。


快照和跟踪

跟踪 -通过寻找一个人或动物去过某地的证据来跟踪他们(dictionary.cambridge.org)

在git中,"你的项目"指您希望保存其历史记录的文件目录树(一个或多个,可能使用子目录组织成树结构)。

Git通过3个步骤,记录了一个“快照"项目的目录树。

项目的每个git快照,然后由"链接"指向项目以前的快照。

一个接一个,一个接一个,我们可以回顾过去,找到你以前的任何快照,或你的遗产。

例如,我们可以从你今天最近的快照开始,然后使用一个链接,回溯到你昨天或上周拍摄的照片,或者当你还是个婴儿的时候,甚至你的母亲是谁,等等。

这被称为“跟踪;在这个例子中,它是跟踪你的生活,或者看到你在哪里留下了足迹,以及你从哪里来。


提交

提交类似于带有单个快照的相册中的一页,因为它不仅包含其中的快照,而且还包含关于该快照的相关元信息。它包括:

  • 我们可以找到这个提交的地址或固定位置,类似于它的页码,
  • 你的项目(文件目录树)在给定时刻的一个快照,
  • 说明快照内容或用途的标题或评论,
  • 快照的日期和时间,
  • 谁拍的最后,
  • 第一个,或更多的链接回溯到之前的快照,比如昨天的快照,或者我们的父母。换句话说"链接"类似于指向其他人的页码,我自己的老照片,或者我的直系父母出生时的页码。

提交是一个组织良好的相册中最重要的部分。


随着时间的推移,家族树有分支和合并

< >强消歧:< /强>“Tree"这里指的不是上面使用的文件目录树,而是一段时间内相关的父和子提交的家族树。

git的家谱结构是以我们自己的人类家谱为蓝本的。

为了更简单地理解链接,我将参考以下内容:

  • parent-commit作为简单的“__abc1”,和
  • child-commit作为简单的"孩子"或“;children"如果复数。

你应该本能地理解这一点,因为它是基于生命之树:

  • 父母可能有一个或多个孩子指向过去的他们,并且
  • 孩子总是有一个或更多的父母他们指向。

因此,除了全新的提交(你可以说是“少年提交”)之外,所有的提交都有一个或多个子提交指向它们。

  • 如果没有子节点指向父节点,则此提交仅为“__abc0”,即下一个子节点将从哪里出生。

  • 只有一个孩子指向一个父母,这只是一个简单的单亲<-孩子关系。

一个简单的,在时间上向后连接的单一父链的折线图:

(older) ... <--link1-- Commit1 <--link2-- Commit2 <--link3-- Commit3 (newest)

分支机构

分支 - A "branch"是一条活跃的发展路线。分支上最近的提交被称为该分支的尖端。 分支的尖端由一个移动的分支头引用 在分支上完成额外的开发时向前。一个Git 库可以跟踪任意数量的分支,但是你的 工作树只与其中一个相关(“当前”;或 “检查out"分支),HEAD指向该分支。(gitglossary) < / p >

git分支还指两个东西:

  • 生长尖端的名称(标识符)和
  • 提交之间链接图中的实际分支。

不止一个孩子指着——>父,就是git所说的“__abc1”。

注:在现实中,任何父母的任何孩子,无论是第一个、第二个还是第三个等等,都可以被视为自己的小分枝,有自己的生长尖端。所以分支不一定是一个有很多节点的长东西,而是一个小东西,由给定父节点的一个或多个提交创建。

父结点的第一个子结点可以说是同一分支的一部分,而该父结点的后续子结点通常被称为“分支机构"”。

实际上,所有子分支(不仅仅是第一个)都来自它的父分支,或者你可以说链接,但我认为每个链接实际上都是一个分支的核心部分。

在形式上,git &;branch&;只是一个名字,就像'foo'一样,赋给家族层次结构的特定生长尖端。这是他们称之为“__abc1”的一种。(标签和遥控器也是参考资料,我稍后会解释。)

裁判 -以refs/开头的名称(例如refs/heads/master),指向一个对象名称或另一个ref(后者被称为A 象征性的ref)。为方便起见,有时可以缩写ref 当用作Git命令的参数时;参见gitrevisions(7) 细节。引用被存储在存储库中

ref命名空间是分级的。使用不同的子层次结构 用于不同的目的(例如refs/heads/ hierarchy被用于 代表当地分支机构)。有一些特殊用途的裁判 不要以裁判开头。最著名的例子是HEAD。(gitglossary) < / p >

(你应该看看你的.git目录中的文件树。这是git结构保存的地方。)

例如,如果你的名字是Tom,那么链接在一起的只包含你的快照的提交,可能就是我们命名为“Tom”的分支。

所以,虽然你可能会认为树枝都是木头,但在git中,树枝只是指它的生长尖端,而不是指通向它的整根木头。

特殊的生长尖端和它的分支被树艺家(一个修剪果树的人)称为“中央领导”。就是git所说的“__abc0”。

主分支始终存在。

线形图:Commit1有2个孩子(或者我们称之为git "分支"):

                parent      children


+-- Commit <-- Commit <-- Commit (Branch named 'Tom')
/
v
(older) ... <-- Commit1 <-- Commit                       (Branch named 'master')
记住,链接只有指向从子节点到父节点。 没有指向相反方向的链接,即从旧到新,也就是从父到子

因此,父提交没有直接的方法来列出它的子提交,或者换句话说,它派生了什么。


合并

孩子有一个或多个的父母。

  • 如果只有一个父元素,这只是一个简单的parent <- child提交。

  • 如果父元素多于一个,git称之为“__abc0”。 每个孩子可以同时指向多个父母,就像有母亲和父亲一样,而不仅仅是母亲

折线图:提交2与2位家长(或我们称之为“__abc1”的git,即来自多个父母的生育):

                parents     child


... <-- Commit
v
\
(older) ... <-- Commit1 <-- Commit2

远程

这个词也有两种不同的意思:

  • 远程存储库和
  • 远程存储库的本地别名,即使用URL指向远程存储库的名称。

远程存储库 -用于跟踪相同项目但驻留在其他地方的存储库。若要与遥控器通信,请参见 取或推。(gitglossary) < / p >

(远程存储库甚至可以是我们自己计算机上的另一个git存储库。) 实际上,每个远程名称都有两个url,一个用于从远程git存储库中推送(即上传提交),另一个用于从远程git存储库中提取(即下载提交)

一个“远程"是一个的名字(一个标识符),它有一个指向远程git存储库的关联URL。(它被描述为URL的别名,尽管它不止于此。)

如果您希望拉入或推入多个远程存储库,则可以设置多个远程存储库。

虽然通常你只有一个,并且它的默认名称是“original”;(表示克隆的上游源)。

起源 -默认的上游存储库。大多数项目至少有一个他们跟踪的上游项目。默认使用origin 为了这个目的。新的上游更新将被取入 远程跟踪分支命名的origin/name-of-upstream-branch,可以使用git branch -r查看。(gitglossary)

Origin表示从哪里克隆存储库。
这个远程存储库被称为“上游”。存储库,而你克隆的存储库被称为“下游”。库。< / p >

上游 -在软件开发中,上游指的是指向作为源代码维基百科分发的软件的原始作者或维护者的方向

上游部门 -被合并到有问题的分支的默认分支(或者有问题的分支被重基于)。 它通过branch..remote和branch..merge进行配置。如果A的上游分支是origin/B,有时我们说“A正在跟踪origin/B”。(gitglossary) < / p >

这是因为大部分水一般都流向你。
你可能会不时地把一些软件推回上游存储库,这样它就可以流向所有克隆它的人

远程跟踪分支机构

首先是远程跟踪分支,只是一个分支名称,就像任何其他分支名称一样。

它指向一个本地增长提示,即最近在你的本地git存储库中的提交。

但是请注意,它还有效地指向远程存储库中的同一提交,您从其中克隆了该提交。

remote-tracking分支 -用于跟踪来自另一个存储库的更改的引用。它通常看起来像refs/remotes/foo/bar (表示它跟踪名为foo的远程对象中名为bar的分支), 并匹配已配置的获取refspec的右侧。远程跟踪分支不应该包含直接的修改 本地提交。(gitglossary) < / p >

假设你克隆的远程文件只有2次提交,就像这样:parent4 <== child-of-4,你克隆了它,现在你的本地git存储库有完全相同的两次提交:parent4 <== child-of-4
你的远程跟踪分支名为起源现在指向child-of-4

现在假设一个提交被添加到远程,因此它看起来像这样:parent4 <== child-of-4 <== new-baby。要更新本地下游存储库,您需要获取new-baby,并将其添加到本地git存储库。现在你的本地远程跟踪分支指向新生儿。您应该明白了,远程跟踪分支的概念就是简单地跟踪您所关心的远程分支的前端。


实时跟踪

首先,我们开始用git跟踪一个文件。

enter image description here

下面是文件跟踪的基本命令:

$ mkdir mydir &&  cd mydir &&  git init         # create a new git repository


$ git branch                                    # this initially reports no branches
#  (IMHO this is a bug!)


$ git status -bs   # -b = branch; -s = short    # master branch is empty
## No commits yet on master


# ...
$ touch foo                                     # create a new file


$ vim foo                                       # modify it (OPTIONAL)




$ git add         foo; commit -m 'your description'  # start tracking foo
$ git rm  --index foo; commit -m 'your description'  # stop  tracking foo
$ git rm          foo; commit -m 'your description'  # stop  tracking foo
#   & also delete foo

远程跟踪

$ git pull    # Essentially does:  get fetch; git merge    # to update our clone

关于取回、合并等还有很多东西要学,但我希望这能让你走在正确的方向上。

没有人提到如何查看已经设置的所有跟踪分支,因此下面是命令,认为这是部分答案,阅读其余部分以理解跟踪分支是什么:

Git分支-vv

查看已设置的所有跟踪分支。

我给你的简短回答是:一个跟踪分支,就像一个正常的分支,但有一个“链接”。对于某些远程存储库的分支,如果远程分支发生了更改,则您的本地分支将在更改时收到通知

git状态