本地分支机构、本地跟踪分支机构、远程分支机构和远程跟踪分支机构有什么区别?

我刚开始使用Git,我对不同的分支感到很困惑。谁能帮我弄清楚以下分支类型是什么?

  • 地方分支机构
  • 本地跟踪分支
  • 远程分支机构
  • 远程跟踪分支机构

它们之间的区别是什么?他们是如何相互合作的?

我想一个快速的演示代码会很有帮助。

118850 次浏览

本地分支机构是只有您(本地用户)才能看到的分支。它只存在于您的本地计算机上。

git branch myNewBranch        # Create local branch named "myNewBranch"

远程分支是远程位置上的分支(在大多数情况下origin)。您可以将新创建的本地分支myNewBranch推送到origin。现在其他用户可以跟踪它。

git push -u origin myNewBranch   # Pushes your newly created local branch "myNewBranch"
# to the remote "origin".
# So now a new branch named "myNewBranch" is
# created on the remote machine named "origin"

远程跟踪分支是远程分支的本地副本。当使用上面的命令将myNewBranch推送到origin时,将在您的计算机上创建一个名为origin/myNewBranch的远程跟踪分支。该远程跟踪分支跟踪origin上的远程分支myNewBranch。您可以使用git fetchgit pull远程跟踪分支更新为与远程分支同步。

git pull origin myNewBranch      # Pulls new commits from branch "myNewBranch"
# on remote "origin" into remote tracking
# branch on your machine "origin/myNewBranch".
# Here "origin/myNewBranch" is your copy of
# "myNewBranch" on "origin"

本地跟踪分支是跟踪另一分支的本地分支机构。这是为了让您可以将提交推送到其他分支/从其他分支拉入提交。在大多数情况下,本地跟踪分支跟踪远程跟踪分支。当您使用带有-u选项的git push命令将本地分支推送到origin时(如上所示),您将本地分支myNewBranch设置为跟踪远程跟踪分支origin/myNewBranch。这是使用git pushgit pull而不指定要推送到或拉入的上游所必需的。

git checkout myNewBranch      # Switch to myNewBranch
git pull                      # Updates remote tracking branch "origin/myNewBranch"
# to be in sync with the remote branch "myNewBranch"
# on "origin".
# Pulls these new commits from "origin/myNewBranch"
# to local branch "myNewBranch which you just switched to.

当地分支机构:

机器上的一个分支,您可以在其中工作并向其中添加提交。您可以使用git branch列出这些分支。

本地分支机构(带跟踪):

被配置为对应于远程分支的普通本地分支。这样做的好处是能够git pullgit push,而不必指定存储库和分支名称。跟踪还会使git status通知您,您的分支何时领先或落后于远程。

远程分支:

只是远程存储库上的一个分支—通常位于GitHub等服务器上。

远程跟踪分支:

远程分支的本地副本。永远不要编辑此分支。其目的是跟踪远程分支的当前状态。远程跟踪分支可以使用git branch -r查看,通常类似于origin/master(回购名称后接斜杠,再接分支名称)。运行git fetch将更新远程跟踪分支以反映相应远程分支的状态。

git branch -avv是我个人最喜欢的,它显示了我的机器上有哪些分支、远程机器上有哪些分支以及每个分支中最新提交的快速概览。-a部分指定应显示所有分支(远程和本地)。末尾的v代表verbose(它显示最后提交的散列和消息)。感谢@Flimm指出第二个v添加了关于哪个本地分支正在跟踪哪个远程分支的信息。

答案很长。

遥控器:

如果您以协作方式使用Git,则可能需要将您的提交与其他计算机或位置同步。在Git的术语中,每个机器或位置被称为遥远的,并且每个机器或位置可以具有一个或多个分支。大多数情况下,您只需要一个名为ABC0的__。要列出所有遥控器,请运行git remote

$ git remote
bitbucket
origin

通过运行__abc0,您可以看到这些远程名称是哪些位置的快捷方式:

$ git remote -v
bitbucket git@bitbucket.org:flimm/example.git (fetch)
bitbucket git@bitbucket.org:flimm/example.git (push)
origin git@github.com:Flimm/example.git (fetch)
origin git@github.com:Flimm/example.git (push)

每个远程数据库在__abc0下都有一个目录:

$ ls -F .git/refs/remotes/
bitbucket/ origin/

计算机上的分支:

TLDR:在本地计算机上,有三种类型的分支:本地非跟踪分支、本地跟踪分支和远程跟踪分支。在远程计算机上,您只有一种类型的分支。

1、各地分公司

您可以通过运行__abc0来查看计算机上所有本地分支的列表:

$ git branch
master
new-feature

每个本地分支在__abc0下都有一个文件:

$ ls -F .git/refs/heads/
master new-feature

计算机上有两种类型的本地分支:非跟踪本地分支和跟踪本地分支。

1.1非跟踪本地分支机构

非跟踪本地分支不与任何其他分支关联。您可以通过运行git branch <branchname>来创建一个。

1.2.跟踪本地分支机构

跟踪本地分支与另一个分支(通常是远程跟踪分支)相关联。您可以通过运行git branch --track <branchname> [<start-point>]来创建一个。

您可以使用git branch -vv查看哪一个本地分支机构正在跟踪分支机构:

$ git branch -vv
master      b31f87c85 [origin/master] Example commit message
new-feature b760e04ed Another example commit message

从该命令的输出中,您可以看到本地分支__abc0正在跟踪远程跟踪分支__abc1,而本地分支__abc2没有跟踪任何内容。

查看哪些分支正在跟踪分支的另一种方法是查看.git/config

跟踪本地分支机构非常有用。它们允许您运行git pullgit push,而无需指定要使用哪个上游分支。如果未将分支设置为跟踪另一个分支,则会出现如下错误:

$ git checkout new-feature
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details


git pull <remote> <branch>


If you wish to set tracking information for this branch you can do so with:


git branch --set-upstream new-feature <remote>/<branch>

远程跟踪分支(仍在您的计算机上)

您可以通过运行git branch -r来查看计算机上所有远程跟踪分支的列表:

$ git branch -r
bitbucket/master
origin/master
origin/new-branch

每个远程跟踪分支在.git/refs/remotes/<remote>/下有一个文件:

$ tree -F .git/refs/remotes/
.git/refs/remotes/
├── bitbucket/
│   └── master
└── origin/
├── master
└── new-branch

将远程跟踪分支视为远程计算机所包含内容的本地缓存。您可以使用git fetch更新您的远程跟踪分支,git pull在后台使用它。

即使远程跟踪分支的所有数据都存储在本地计算机上(类似于缓存),它也不会被称为本地分支。(至少,我不会这样称呼它!)它只是被称为远程跟踪分支。

远程计算机上的分支:

您可以通过运行__abc0来查看所有远程分支(即远程计算机上的分支):

$ git remote show origin
* remote origin
Fetch URL: git@github.com:Flimm/example.git
Push  URL: git@github.com:Flimm/example.git
HEAD branch: master
Remote branches:
io-socket-ip            new (next fetch will store in remotes/origin)
master                  tracked
new-branch              tracked
Local ref configured for 'git pull':
master     merges with remote master
new-branch merges with remote new-branch
Local ref configured for 'git push':
master     pushes to master     (up to date)
new-branch pushes to new-branch (fast-forwardable)

此__abc0命令通过网络向远程计算机查询其分支。它不会更新本地计算机上的远程跟踪分支,请为此使用git fetchgit pull

从输出中,您可以通过查看标题“远程分支”来查看远程计算机上存在的所有分支。(忽略标记为“过时”的行)。

如果您可以登录到远程计算机并在文件系统中找到存储库,则可以查看refs/heads/下的所有分支。

小抄:

  • 要安全删除本地分支(无论是跟踪还是非跟踪),请执行以下操作:

      git branch -d <branchname>
    
  • 要强制删除本地分支(无论是跟踪还是非跟踪),请执行以下操作:

      git branch -D <branchname>
    
  • 要删除远程跟踪分支:

      git branch -rd <remote>/<branchname>
    
  • 要创建新的本地非跟踪分支,请执行以下操作:

      git branch <branchname> [<start-point>]
    
  • 创建新的本地跟踪分支:(注意,如果指定了<start-point>,并且是类似于origin/foobar的远程跟踪分支,则自动包括--track标志)

      git branch --track <branchname> [<start-point]
    

    示例:

      git branch --track hello-kitty origin/hello-kitty
    
  • 要删除远程计算机上的分支:

      git push --delete <remote> <branchname>
    
  • 要删除所有过时的远程跟踪分支,即远程计算机上不再存在的相应分支,请执行以下操作:

      git remote prune <remote>
    

您可能已经注意到,在某些命令中,您使用__abc0,而在其他命令中,您使用__abc1。例如:git branch origin/hello-kittygit push --delete origin hello-kitty

这似乎是武断的,但有一种简单的方法可以记住何时使用斜杠,何时使用空格。当您使用斜杠时,您指的是您自己计算机上的远程跟踪分支,而当您使用空格时,您实际上是在通过网络处理远程计算机上的分支。

概述

热释光;博士-这是有组织的,所以你可以跳到你需要知道的。

以下是我将介绍的内容:

  • 快速概述-什么是4种类型的分支以及在哪里可以找到它们
  • 简明词汇.与分支机构有关的基本原则和术语
  • 调查-如何检查本地和远程分支机构
  • 相关文件-配置文件
  • 配置-如何查看和设置分支配置
  • 协作-如何使用远程分支

快速概览

在我们的当地的储存库上,本地分支是指头在这里的名称。

远程分支遥远的储存库上的名称,其指头在那里


简单的分支是引用一个事物的本地名称:

  1. 它直接指向局部头部(即,指向特定的提交;生长尖端)

跟踪分支是引用以下两项的本地名称:

  1. 它直接指向局部头部(即,指向特定的提交;生长尖端),
  2. 远程存储库上的它象征性地指向第二个分支。

有两种跟踪分支:

  • 当地的—分支指向本地报头的位置。
    它们被称为本地-跟踪-分支(更多信息见下文。)

  • 遥远的—分支指向远程磁头的本地副本。
    它们被称为远程-跟踪-分支(更多信息见下文。)


下面是4种类型的分支,我们在哪里看到它们,以及它们如何映射:

WHERE    ---BRANCH TYPE--------     --REFERENCE TARGETS-------


--------------------------------------------------------------
Remote   simple branch -----------> remote head (a commit ID)


--------------------------------------------------------------
Local    simple branch -----------> local  head (a commit ID)




Local    local  tracking-branch --> local  head (a commit ID1)
--> Remote-name/branch-name


Local    remote tracking-branch --> local  head (a commit ID2)
--> Remote-name/branch-name
--------------------------------------------------------------

简短的词汇表

术语远程的分支似乎过载。

跟踪分支尤其令人困惑,因为它和跟踪分支不是一回事。

'a snapshot'      - A recording of the state of one or more files
and their contents at a given moment in time.


'a commit'        - A container holding one snapshot, the date and
time it was  recorded, who recorded it, and a
comment to say what it's all about.


'a repository'    - A repository of commits, organized so we can
look thru them, going backwards in time.


Much like photos added in sequence to a photo
album book, to record our own history, each commit
contains a snapshot of the exact state of our
project at a given moment in time.
                    

It is used to be able to look backwards in time to
how it was at any recorded previous time.

'Remote'          - (Upper case) Short for 'a named remote repository'
(of commits, of snapshots)


'remote'          - (Lower case) Located on  another     git repository
'local'           -              Located on  your local  git repository

'a head'          - A specific young commit, with no children yet of
it's own (i.e. no other commits yet pointing to it),
but which may link backwards in time to one or more
of it's natural parents.


Also called a growing tip.
Initially set to a <start-point>.




'a branch'        - A symbolic name (i.e. an identifier) pointing
to one specific head, and possibly, depending on
the branch type, also pointing to a remote branch.


The term 'branch' can also refer to a specific
linked list of multiple commits (plural), starting
from the growing tip (or most recent baby), and
linking offspring to their parent(s) backwards in
time.
                   


'tracks'          - As we move forward, tracks are what we leave behind.


'tracked'         - To be followed, as in, to come afterwards, or after
the fact, by way of the evidence left behind, of the
a state of being of the thing being tracked, as it
moves forwards in time.


'tracking'        - The process of capturing and organizing snapshots of
our project so we can later look backwards in time
to find how it previously was.

'tracking-branch' - This term is somewhat redundant, and confusing,
but does have a specific, important meaning.


I have deliberately added the hyphen, because this
term does NOT mean simply 'tracking branch'.  (Grab
your aspirin, and a cold pack for your head, lol.)




Because all branches in git are used for, and only
used for, tracking your project, therefore it could
be said that ALL branches are actually
'tracking-branches', but we don't call them that.


Instead we call them, simply 'branches'.




But then what is a 'tracking-branch'?

         TL;DR      A 'tracking-branch' is a local name that points to
two branches at the same time.
                    

So when you read  'tracking-branch,  it might be
helpful to instead think:  'branch-pair'.


(Normal branches only point to one thing, the
head, which is the commit at a growing tip.
And they do not have any symbolic pointers.)




1) The first branch a 'tracking-branch' points to
is the same as for any other branch:  a local head,
(i.e. a young commit in our local repository without
any children.)  This is where a tracking-branch
keeps a full local copy of a remote branch.


Note that it doesn't necessiarialy hold a full
duplicate copy of the entire second, remote
repository.  If you have cloned the remote
repository then you already have most, if not all
of their commits in your own local repository.




2) The second branch a 'tracking-branch' points to
is a branch on a remote repository.


It does this with a <remote-name>/<branch-name>.
The 'remote-name' is used to find the URL to the
remote repository.  See `git remote -v`.

                    Why point to two branches?


This is to be able to operate on two heads at the
same time, like to copy commits from one head to
the other as `git fetch` and `git push` does.




We have two types of 'tracking-branches' (both on
our local repository):
                    

'local  tracking-branches',
with a simple     branch name,  and
                           

'remote tracking-branches',
with a path-style branch name.
                           

See `git branch -avv`.  For example:

enter image description here

  • 这里输出

    的前两行是局部跟踪分支。前缀为星号(*)的master告诉我们,master是当前默认的分支(即,签出到我们的工作区域中的内容)。顺便说一下,名称masterrefs/heads/master的缩写。

  • 第3行输出是简单的本地分支机构

  • 第4行输出完全不是分支,而是指向默认远程跟踪分支的第二本地头(除了我们的正常本地头之外),或者在该示例中指向以下分支之一。使用git remote set-head <remote-name> <remote tracking-branch name>进行设置。(请注意,这与git remote show <remote-name>返回的HEAD不同,后者是远程存储库的HEAD的下载值。)

  • 最后两行输出是远程跟踪分支。

请注意,所有分支都引用一个提交ID(十六进制数字)。remotes/origin/HEAD不是一个分支,因此它没有这个。

另请注意,前两行和后两行还具有对远程(在本例中,远程名为__abc0)上的分支的符号引用。

这里的“主人”是我们当地的工作分支。并且remotes/origin/master是(通过git fetchgit clonegit pull)从远程origin获取的名为master的分支的本地副本。

(顺便说一下,__abc0是我们最初克隆的远程存储库的默认名称,使用__abc1命令。)


                    So our 'remote tracking-branches' are not remote
branches, on a remote repository, but rather are
local branches, which have a local head of their
own, pointing to a local commit, and also at the
same time symbolically pointing, to a remote
branch.


With `git branch -avv`, notice how two branches can
point to origin/remote:
                    

* the first  being the  'local-tracking-branch'
with the name        'master', and with the
'[origin/master]' extra clause,  and
                      

* the second being the 'remote-tracking-branch'
with the name 'origin/master'.




NOTE: Though they point to the same remote branch,
the local commit head is not always the same!
                    

Thus they are actually two different branches.
                    

The 'local-tracking-branch' is our working branch,
and the 'remote-tracking-branch' is a copy of the
remote's branch that we cloned from or fetched to
update.

调查

遥控器

git remote                      # List names of known Remotes


git remote -v                   # List names of known Remotes and
#   show the 2 URL's pointing to them
#
#  See '[remote "<names>"]' in
#    $ cat .git/config

远程分支(位于远程存储库上)

git remote show <remote-name>   # Download and view
#   a specific Remote's info.


# for example, let's download the information for
# two remotes named origin and upstream:

enter image description here

  • 前导星号(*)是一个项目符号,用于标记来自给定远程设备的数据的开始。我们请求从两个遥控器下载,所以我们有两个子弹。

  • 1号线路输出给出遥控器的名称,以单词“ REMOTE ”开头。

  • 第二和第三行报告远程命名origin的本地配置的获取和推送URL。也可以使用git remote -v查看它们。

  • 第四名线报告远程存储库中的HEAD。你不能设置这个头。它也不与本地头部相同,也不是来自git branch -avv的远程的本地读取

  • 6号线上

    开始的是远程存储库拥有的分支的列表

    远程分支: 主人追踪 跟踪的

    更新
  • 然后Torek对剩下的行说出

Git Remote Show所做的全部工作就是使用git ls-remote通过互联网电话调用[远程],并将它们的引用与您的引用进行比较,以根据这些结果猜测git fetchgit push会做什么。(如果你使用git pull,那就意味着运行git fetch,然后运行git merge。__abc6命令也试图猜测它将做什么。)

本地分支(位于本地存储库中)

git branch -avv  # Show ALL  'local branches', verbosely;  (3 types):




git branch -rv   # -- type 1 -------------------------------------
# Show ONLY 'local branches' that point to
# 'remote branches' (-r = remote; -v = verbose)
#
#   This lists your 'Remote tracking branches'!
#     From:  $ tree .git/refs/remotes/*
#
#      They allow us to move snapshots between
#       repositories, and to keep a copy of
#       Remote's branches locally.


git branch -vv   # -- types 2 and 3 ------------------------------
# Show ONLY 'local branches', that point to local
# things, but his includes two different types of
#  branches mixed together, for example:


* master  de430b6 [origin/master] <comment describing this branch>
updates 3c40299 [origin/updates] <comment describing this branch>
foo     de430b6  <comment describing this branch>

请注意,前两个名为masterupdates的分支(如上)在其提交编号后都有一个附加字段。例如,对于名为“ master ”的分支,该字段__abc2。

这告诉我们,这两个分支不是普通的本地分支,而是局部跟踪分支。与上面的“远程跟踪分支”类似,它们也象征性地指向远程分支。因此,在这种情况下,master不仅指向本地储存库中的分支,而且还指向远程储存库中的origin/master

这些额外的字段由.git/config中的参数设置。

相反,这里的foo是简单的正常分支,即非跟踪。


相关文件

 cat .git/config                       # '[branch "<names>"]' are local
#    tracking branches


ls -F .git/refs/heads/*               # 'Local' branch names & heads:
#   both tracking and non-tracking


ls .git/refs/remotes/<remote-name>/*  # 'Remote' tracking branch names & heads

配置

使用git branch,git checkout -b

创建,或者 通过克隆具有git clone的远程存储库,或者 通过直接编辑.git/config或使用以下命令进行显式管理:


遥控器

通过克隆Git存储库,使用Git Remote隐式

创建 git clone.

  • git remote add-明确添加新的远程名称(到.git/config)
  • git remote rename
  • git remote remove-删除遥控器
  • git remote prune-删除已在远程服务器上删除的任何本地远程跟踪分支

设置属性,使用:

  • git set-url-设置一个URL,或替换远程的URL

  • git set-url --add-将URL附加到远程的URL列表中

  • git set-url --delete-删除所有与模式匹配的URL

  • git set-branches-更改已跟踪分支的设置

  • git set-branches --add-追加,而不是完全替换当前跟踪的分支列表

  • git set-head-设置默认远程分支(即远程的头)

  • git set-head --auto—查询远程以设置远程分支的本地标头

  • git set-head --delete-删除默认远程分支(即远程设备的头部)

树枝

git branch  [--set-upstream | --track | --no-track]  [-l] [-f]               <NewBranchName> [<start-point>]   # create branch         (start point defaults to HEAD)


git branch  (--set-upstream-to=<upstream-branch> | -u <upstream-branch>)       [<BranchName>]                  #   link to upstream branch
git branch --unset-upstream                                                    [<BranchName>]                  # unlink to upstream branch




git branch --edit-description                                                  [<BranchName>]                  # edit   branch description




git branch (-m | -- move | -M)                              [<oldBranchName>] <newBranchName>                  # rename (move) branch; -M = force


git branch (-d |           -D) [-r]                                             <BranchName>...                # delete branch

合作

使用默认配置,当您git clone时,它会自动设置您的远程和跟踪分支。但请注意,有一些配置设置将禁用或更改其工作方式。


小费git fetchgit push上使用--dry-run选项,以在执行之前查看将会发生什么。


使用git fetch(可能通过调用git pull)来更新远程提交的本地副本,以使您获得最新状态。

如果不包括,则使用默认值。您可以在[remote "<remote-name>"]下的fetch=属性中的.git/config中查看默认值。这可能看起来像这样:

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*

语法[+]?<source>:<destination>。这意味着从.git/refs/heads/*(远程存储库中的普通简单分支)获取REFS(通常是提交和标记),并将它们放入我们的本地.git/refs/remotes/origin/*分支(跟踪分支)中。酷,嗯!顺便说一句,“+”表示即使这不是快进,也要更新。


使用git push <remote> <branch>将本地提交发送到您有权写入的远程存储库。


我希望这一切都是正确的。