Git:什么是跟踪分支?

jer*_*ith 144 git version-control branch

有人可以解释一个"跟踪分支",因为它适用于git?

这是git-scm.com的定义:

Git中的"跟踪分支"是连接到远程分支的本地分支.当您按下并拉动该分支时,它会自动推送并拉到与其连接的远程分支.

如果您始终从同一个上游分支拉入新分支,并且您不想明确使用"git pull",请使用此选项.

不幸的是,对于git和来自SVN的新手来说,这个定义对我来说绝对没有意义.

我正在阅读" Git的实用指南 "(顺便说一句好书),他们似乎建议跟踪分支是一件好事,并且在创建第一个遥控器(原点,在这种情况下)后,你应该将您的主分支设置为跟踪分支,但遗憾的是,它不包括为什么跟踪分支是一件好事,或者通过将主分支设置为原始存储库的跟踪分支而获得的好处.

有人可以赐教(英文)吗?

Ass*_*vie 111

ProGit本书一个很好的解释:

跟踪分支

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

克隆存储库时,它通常会自动创建跟踪origin/master的主分支.这就是为什么git push和git pull开箱即用而没有其他参数.但是,您可以根据需要设置其他跟踪分支 - 不跟踪原点分支但不跟踪主分支的分支.这个简单的例子就是你刚看到,运行的例子git push.如果你有Git 1.6.2或更高版本,你也可以使用git pull速记:

$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "serverfix"
Run Code Online (Sandbox Code Playgroud)

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

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch refs/remotes/origin/serverfix.
Switched to a new branch "sf"
Run Code Online (Sandbox Code Playgroud)

现在,您的本地分支git push将自动推送和拉出git pull.

  • 只想清理一下:"从远程分支中检出本地分支会自动创建所谓的跟踪分支." 这是误导.如果没有--track选项,您创建的任何分支都将无法跟踪. (17认同)
  • @ JohnO,根据:https://www.sbf5.com/~cduan/technical/git/git-4.shtml --track 默认开启,因此没有必要。 (3认同)

Von*_*onC 38

Progit书中提到:

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

不完全是.SO问题" 难以理解git-fetch "包括:

没有本地跟踪分支的概念,只有远程跟踪分支.
所以origin/master是一个远程跟踪分行masterorigin回购.

但实际上,一旦你建立了上游分支关系:

  • 像当地的一个分支 master
  • 和远程跟踪分支一样 origin/master

然后,您可以将其master视为本地跟踪分支:它跟踪远程跟踪分支 origin/master,该分支轮流跟踪上游存储库 的主分支origin.

替代文字

  • @SherylHohman否:本地分支机构不会"直接"或"间接"跟踪任何内容.它将跟踪您将分配给它的远程跟踪分支.在fork的情况下,最佳做法是跟踪公共分支(如master)的上游(原始仓库),以及跟踪新分支(您的PR或功能分支)的原始(远程分支):请参阅https:// stackoverflow.com/a/21847690/6309 (3认同)
  • @VonC - 声明“没有本地跟踪分支的概念,只有远程跟踪分支。” 有趣的是 b/c 在分支周围有如此相互矛盾的术语。这个经常引用的链接 https://web.archive.org/web/20130419172453/http://www.gitguys.com/topics/tracking-branches-and-remote-tracking-branches 区分“跟踪分支”和“远程跟踪分支”。他们称 origin/master 为“远程跟踪分支”——我同意——但他们也称“master”为“跟踪分支”。什么是主跟踪?他们错了还是术语问题? (3认同)
  • @Howiecamp他们称之为"名为master的跟踪分支"只是一个本地分支主机,它具有一个相关的远程跟踪分支origin/master,这里记忆了从源获取的关于其远程主分支的最后一个SHA1.因此,它是指定"具有上游分支的本地分支"的"捷径" (2认同)

hag*_*wal 30

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

在此输入图像描述 在此输入图像描述 在此输入图像描述 在此输入图像描述 在此输入图像描述 在此输入图像描述


跟踪分支和"git fetch":

在此输入图像描述 在此输入图像描述 在此输入图像描述

  • 您的注释很有用,但请考虑使用文本而不是图像 https://meta.stackoverflow.com/questions/303812/discourage-screenshots-of-code-and-or-errors/307500#307500 (3认同)

agr*_*lev 10

这就是我添加跟踪分支的方式,以便我可以从它拉入我的新分支:

git branch --set-upstream-to origin/Development new-branch
Run Code Online (Sandbox Code Playgroud)


Ell*_*iew 8

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

因此,我们可能应该将普通的 git 称为“分支”、“跟踪分支”,但我们没有。相反,我们将它们的名称缩短为“分支”。


因此,这就是“跟踪分支”这个术语如此令人困惑的部分原因:对于外行来说,它很容易意味着两种不同的东西。

在 git 中,术语“Tracking-branch”是更完整术语的简称:“Remote-tracking-branch”

一开始最好用更正式的术语来代替,直到您对这些概念更加熟悉为止。


让我们将您的问题改写为:

什么是“远程跟踪分支”?

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


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

以下是介绍/概述,但您可能会发现这篇优秀的文章也提供了丰富的信息。


Git 是什么以及它的用途

git 存储库就像一个家庭相册: 它保存历史快照,显示过去的情况。“快照”是在给定时刻对某事物的记录。

git 存储库不仅限于保存人类家庭照片。相反,它可以用来记录和组织随时间演变或变化的任何事物

基本想法是创建一本书,以便我们可以轻松回顾过去,

  • 将过去的时间与现在或其他时刻进行比较,并且
  • 重新创造过去。

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


快照和跟踪

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

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

Git 通过 3 个步骤的过程,在给定时刻记录项目目录树的“快照”。

然后,项目的每个 git 快照都通过指向项目先前快照的“链接”进行组织。

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

例如,我们可以从您今天最新的快照开始,然后使用链接,向后查找您昨天或上周拍摄的照片,或者您还是婴儿时的照片,甚至您的母亲是谁, ETC。

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


提交

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

  • 我们可以找到此提交的地址或固定位置,类似于其页码,
  • 您的项目(文件目录树)在给定时刻的快照,
  • 说明快照的内容或用途的标题或评论
  • 该快照的日期和时间,
  • 谁拍了这张快照,最后,
  • 一个或多个在时间上向后链接到先前的相关快照,例如昨天的快照,或到我们的父母。换句话说,“链接”类似于指向我自己的其他旧照片或我的直系父母出生时的页码的指针。

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


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

消歧义: 这里的“树”不是指上面使用的文件目录树,而是指随时间推移相关父级和子级提交的家谱。

git 家谱结构是根据我们自己的人类家谱建模的。

为了帮助您以简单的方式理解链接,我将参考以下内容:

  • 提交只是一个“”,并且
  • 提交简单地称为“”或“子”(如果是复数)。

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

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

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

  • 如果没有孩子指向父母,那么这个提交只是一个“成长提示”,或者下一个孩子将从哪里出生。

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

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

(older) ... <--link1-- Commit1 <--link2-- Commit2 <--link3-- Commit3 (newest)
Run Code Online (Sandbox Code Playgroud)

分支机构

分支- “分支”是一条活跃的开发线。分支上的最新提交称为该分支的提示。分支的尖端由分支头引用,分支头随着分支上完成的额外开发而向前移动。单个 Git 存储库可以跟踪任意数量的分支,但您的工作树仅与其中一个分支(“当前”或“签出”分支)相关联,并且 HEAD 指向该分支。(吉特术语表

git 分支还指两件事:

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

多个子节点指向 --at a-->parent,这就是 git 所说的“分支”。

注意:实际上,任何父母的任何孩子,无论天气第一、第二或第三等,都可以被视为他们自己的小树枝,有自己的成长尖端。因此,分支不一定是一个具有许多节点的长事物,而是一个小事物,仅由给定父级的一个或多个提交创建。

父级的第一个子级可以说是同一分支的一部分,而该父级的连续子级通常称为“分支”。

实际上,所有子级(不仅仅是第一个)都来自其父级,或者您可以说link,但我认为每个link实际上是branch的核心部分。

从形式上来说,git“branch”只是一个名称,例如“foo”,是给家族层次结构中特定的成长尖端的。这是他们所谓的“ ref ”的一种类型。(我稍后将解释的标签和遥控器也是参考。)

ref - 以 refs/ 开头的名称(例如 refs/heads/master),指向对象名称或另一个引用(后者称为符号引用)。为了方便起见,当用作 Git 命令的参数时,有时可以缩写 ref;有关详细信息,请参阅 gitrevisions(7)。参考文献存储在存储库中。

ref 命名空间是分层的。不同的子层次结构用于不同的目的(例如,refs/heads/层次结构用于表示本地分支)。有一些特殊用途的引用不以 refs/ 开头。最显着的例子是 HEAD。(吉特术语表

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

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

因此,虽然你可能认为树枝都是木头,但在 git 中,树枝只是对其生长尖端的名称,而不是通向它的整根木头的名称。

树艺师(修剪果树的人)称之为“中心领导者”的特殊生长尖端及其分支就是 git 所说的“主人”。

master 分支始终存在。

线图:带有 2 个子项的 Commit1(或者我们所说的 git“分支”):

                parent      children

                        +-- Commit <-- Commit <-- Commit (Branch named 'Tom')
                       /
                      v
(older) ... <-- Commit1 <-- Commit                       (Branch named 'master')    
Run Code Online (Sandbox Code Playgroud)

请记住,链接指向从子级到父级。没有指向相反方向的链接,即从旧到新,即从父到子。

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


合并

孩子有一个或多个父母。

  • 对于只有一个父级的情况,这只是一个简单的父级 <-- 子级提交。

  • 对于多个父级,这就是 git 所说的“合并”。每个孩子可以同时指向多个父母,就像同时拥有母亲和父亲,而不仅仅是母亲一样。

线图:带有 2 个父项的 Commit2(或者我们所说的 git“合并”,即从多个父项生成):

                parents     child

           ... <-- Commit
                        v
                         \
(older) ... <-- Commit1 <-- Commit2  
Run Code Online (Sandbox Code Playgroud)

偏僻的

这个词也用来表示两种不同的意思:

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

远程存储库- 用于跟踪同一项目但驻留在其他地方的存储库。要与远程通信,请参阅获取或推送。(吉特术语表

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

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

如果您想拉取或推送到多个远程存储库,您可以设置多个遥控器。

尽管通常您只有一个,但它的默认名称是“origin”(意味着您克隆的上游源)。

origin - 默认的上游存储库。大多数项目至少有一个他们跟踪的上游项目。默认情况下,原点用于此目的。新的上游更新将被提取到 名为 origin/name-of-upstream-branch的远程跟踪分支中,您可以使用 gitbranch -r 看到它。(吉特术语表

Origin 表示您从何处克隆存储库。
该远程存储库称为“上游”存储库,而您的克隆存储库称为“下游”存储库。

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

上游分支- 合并到相关分支的默认分支(或重新定位相关分支)。它是通过branch..remote 和branch..merge 配置的。如果 A 的上游分支是 origin/B,有时我们会说“A 正在跟踪 origin/B”。(吉特术语表

这是因为大部分水通常都会流向您。
有时,您可能会将某些软件推送回上游存储库,这样它就可以流向所有克隆它的人。

远程追踪分支

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

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

但请注意,它实际上还指向远程存储库中您克隆提交的同一提交。

远程跟踪分支- 用于跟踪另一个存储库的更改的引用。它通常看起来像 refs/remotes/foo/bar (表明它跟踪名为 foo 的远程中名为 bar 的分支),并与配置的 fetch refspec 的右侧匹配。远程跟踪分支不应包含直接修改或对其进行本地提交。(吉特术语表

假设您克隆的远程服务器只有 2 个提交,如下所示:parent4 <== child-of-4,然后您克隆它,现在您的本地 git 存储库具有完全相同的两个提交:parent4 <== child-of-4您名为origin 的
远程跟踪分支现在指向.child-of-4

现在假设将提交添加到远程,因此它看起来像这样: parent4 <== child-of-4 <== new-baby。要更新本地下游存储库,您需要获取 new-baby,并将其添加到本地 git 存储库。现在您的本地远程跟踪分支指向 new-baby。您明白了,远程跟踪分支的概念只是跟踪您之前关心的远程分支的尖端内容。


实际追踪

首先我们开始使用 git 跟踪文件。

在此输入图像描述

以下是与文件跟踪相关的基本命令:

$ 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
Run Code Online (Sandbox Code Playgroud)

远程追踪的实际应用

$ git pull    # Essentially does:  get fetch; git merge    # to update our clone
Run Code Online (Sandbox Code Playgroud)

关于获取、合并等还有很多东西需要学习,但我希望这应该能让你朝着正确的方向前进。