Git 分支:主与源/主与远程/源/主



我认为我走在理解 git 基本概念的正确轨道上。

我已经设置并克隆了一个远程存储库。我还创建了一个服务器端空存储库,并将我的本地存储库链接到它。

我的问题是我不明白以下两者之间的区别:

    源/主/源/
  • 源/主

据我了解,master是一个本地分支,而remotes/origin/master是一个远程分支。

究竟什么是起源/主人

克隆远程仓库并运行git branch -a(以显示 git 知道的所有分支(。 它可能看起来像这样:

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

在这里,master是本地存储库中的一个分支。 remotes/origin/master 是远程上名为 master 的分支,名为 origin 。 您可以将其称为 origin/master ,如:

git diff origin/master..master

您也可以将其称为remotes/origin/master

git diff remotes/origin/master..master

这只是引用同一事物的两种不同方式(顺便说一下,这两个命令都意味着"向我显示远程master分支和我的master分支之间的更改(。

remotes/origin/HEAD是名为 origin 的遥控器的default branch。 这使您可以简单地说origin而不是origin/master

我这样的傻瓜的简短回答(从托雷克偷来的(:

  • 起源/大师是"上次我检查时师父在那边的地方">
  • 父是"师父在哪边,根据我一直在做什么">

从技术上讲,您的 Git 存储库中实际上根本没有任何"远程"的东西1,只有本地名称应该对应于另一个不同存储库中的名称。 名为 origin/whatever 的那些最初将与克隆的存储库中的那些匹配:

git clone ssh://some.where.out.there/some/path/to/repo # or git://some.where...

创建另一个存储库的本地副本。 在此过程中,它会记录那里的所有分支,并提交这些引用,并将其以名称refs/remotes/origin/粘贴到您的本地存储库中。

根据您在git fetch或等效更新"我的 some's some.where.out.there"副本之前的时间,他们可能会更改其分支、创建新分支并删除一些分支。 当你做你的git fetch(或git pull实际上是获取加合并(时,你的存储库将复制他们的新工作,并根据需要更改所有refs/remotes/origin/<name>条目。 正是fetch的那一刻使一切匹配(嗯,还有最初的克隆,以及一些push的情况——基本上只要 Git 有机会检查——但请参阅下面的警告(。

Git 通常让你将自己的refs/heads/<name>称为 <name> ,而远程的称为 origin/<name> ,这一切都是有效的,因为很明显哪一个是哪个。 有时可以创建自己的分支名称,使其不明显,但在它发生之前不要担心。:-) 只需给 Git 一个最短的名称,使其显而易见,它就会从那里开始:origin/master是"上次我检查时师父在那边的地方",master是"根据我一直在做的事情,师父在这里的位置"。 根据需要运行git fetch以更新"主站在那边"上的 Git。


警告:在低于 1.8.4 的 Git 版本中,git fetch有一些模式不会更新"主站在那里的位置"(更准确地说,是不更新任何远程跟踪分支的模式(。 运行git fetch origin,或git fetch --all,甚至只是git fetch确实会更新。 运行git fetch origin master则不会。 不幸的是,这种"不更新"模式是由普通git pull触发的。 (这主要只是一个小烦恼,在 Git 1.8.4 及更高版本中已修复。


1嗯,有一件事叫做"遥控器"。 但那也是本地的! origin这个名字是Git所说的"远程"。 它基本上只是您在进行克隆时使用的 URL 的简称。 这也是origin/master origin的来源。 名称origin/master称为远程跟踪分支,有时会缩短为"远程分支",尤其是在较旧或更非正式的文档中。

我会尽量让初学者@ErichBSchulz的答案更简单:

  • 源/主是远程存储库上主分支的状态
  • master 是本地存储库上主分支的状态
  1. origin - 这是指向远程的自定义和最常见的名称。

$ git remote add origin https://github.com/git/git.git --- 您将运行此命令以将 github 项目链接到源。这里的原点是用户定义的。您可以按$ git remote rename old-name new-name重命名它


    master
  1. - Git 中的默认分支名称为 master。适用于远程和本地计算机。

  1. 源/主 - 这只是一个在远程存储库中引用主分支的指针。记得我说过原点指向远程。

$ git fetch origin - 将对象和引用从远程存储库下载到本地计算机 [源/主]。这意味着它不会影响您的本地主分支,除非您使用 $ git merge origin/master 合并它们。请记住在运行此命令之前签出需要合并的正确分支

注意:提取的内容表示为远程分支。借助 Fetch,您有机会在将更改集成到项目副本之前查看更改。要显示您和远程$git diff master..origin/master之间的变化<</em>

div class="one_answers">

一个澄清(也是让我困惑的一点(:

"remotes/origin/HEAD 是默认分支"并不是真的正确。

远程/

源/主是远程存储库中的默认分支(上次检查时(。 HEAD不是一个分支,它只是指向一个分支。

将HEAD视为您的工作区域。当您以这种方式考虑时,"git checkout 分支名称"对于将工作区文件更改为特定分支的文件是有意义的。 您将分支文件"签出"到您的工作区。用于所有实际目的的HEAD是您在工作区域中可见的内容。

我认为这个 git 斜杠表示法可能最好通过查看您的 .git 文件夹来理解。


例如,这是我的 .git 的一个缩写树,用于 LibreOffice 源代码库。

linux 中,查看此内容很有用sudo apt-get install tree
Windows中,我认为tree命令可能仍然有效。

向下滚动并查看底部附近的参考文献(又名"参考文献"(:

$ tree  
.  
├── branches  
├── config  
├── description  
├── FETCH_HEAD  
├── gitk.cache  
├── HEAD  
├── hooks  
│   ├── applypatch-msg.sample  
    ...
├── index  
├── info  
│   └── exclude  
├── logs  
│   ├── HEAD  
│   └── refs  
│       ├── heads  
│       │   ├── master  
│       │   └── remotes  
│       │       └── origin  
│       └── remotes  
│           └── origin  
│               ├── distro  
│               │   ├── cib  
│               │   │   └── libreoffice-6-0  
│               │   ├── collabora  
│               │   │   └── cp-6.0  
│               │   └── lhm  
│               │       └── libreoffice-5-2+backports  
│               ├── HEAD  
│               ├── libreoffice-6-2  
│               ├── master  
│               └── private  
│                   └── mst  
│                       └── sw_redlinehide_4a  
├── objects  
│   ├── info  
│   └── pack  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.idx  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.pack  
│       ├── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.idx  
│       └── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.pack  
├── ORIG_HEAD  
├── packed-refs  
└── refs  
    ├── heads  
    │   ├── master  
    │   └── remotes  
    │       └── origin  
    ├── remotes  
    │   └── origin  
    │       ├── distro  
    │       │   ├── cib  
    │       │   │   └── libreoffice-6-0  
    │       │   ├── collabora  
    │       │   │   └── cp-6.0  
    │       │   └── lhm  
    │       │       └── libreoffice-5-2+backports  
    │       ├── HEAD  
    │       ├── libreoffice-6-2  
    │       ├── master  
    │       └── private  
    │           └── mst  
    │               └── sw_redlinehide_4a  
    └── tags  
        └── libreoffice-6-2-branch-point  
32 directories, 45 files

如果这样布置,可能会不那么令人困惑,但事实并非如此:

repositories (i.e. independent trees)
├──local
│  └──master
│
└──origin1
│  └──master
└──origin2
   └──master

我们有三种基本类型的引用:远程标签

  • .git/refs/heads拥有我们的本地主人

  • .git/refs/remotes可以容纳许多遥控器,尽管目前我们只有它的起源

  • .git/refs/tags(在别处讨论(。

因此,起源是我们唯一的远程。 它拥有原产地/主。


我们发现我们有 2 个 HEADS(指向当前分支的指针(,一个本地分支和一个远程分支:

$ cat .git/HEAD                        #         local:  HEAD -> master
ref: refs/heads/master
$ cat .git/refs/remotes/origin/HEAD    # remote origin:  HEAD -> master
ref: refs/remotes/origin/master

如果您列出分支

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/aoo/aw080
  remotes/origin/aoo/trunk
  remotes/origin/distro/capgemini/cg-4.1
  remotes/origin/distro/cib/libreoffice-5-0
  remotes/origin/distro/cib/libreoffice-5-1
  remotes/origin/distro/cib/libreoffice-5-2
  ...
  • 列出的第一个分支((是唯一不是远程分支的分支。 所以在这种情况下,我们有一个本地分支。 我们将从这里开始我们自己的工作,用于我们自己的新分支和后续提交。

接下来,您可能有许多远程跟踪分支,我们在这里这样做。 您知道这些是远程跟踪分支,因为它们以">remotes/"为前缀。 此处显示的那些适用于远程命名源。

  • 因此,第二行是原点的当前分支指针。 遥控器/来源:HEAD --指向-->主控。 这表明在远程仓库中,当前分支是它们名为 master 的分支(不要与我们名为 master 的本地分支混淆(。

  • 其余的分支在您的 .git/refs/树中找不到,但您可以在 .git/packed-refs 中找到它们。

当我们 git fetch 时,我们会将更改从远程存储库下载到我们的远程跟踪存储库中。

当我们 git merge 时,我们将这个本地远程跟踪存储库中的更改合并到我们工作的本地分支或分支中,在本例中为我们的主分支。

(当我们 git pull 时,我们会在一个操作中执行这两个步骤。


有趣的是,这些用于 master本地远程 UUID 当前指向同一节点(也称为"提交"(:

$ cat refs/heads/master                   # local         master
1ca409292272632f443733450313de5a82c54a9c
$ cat refs/remotes/origin/master          # remote origin master
1ca409292272632f443733450313de5a82c54a9c

因此,我们的本地主节点指向与远程源主机相同的位置:

[local] master = [remote] origin master

最后,我认为看看.git/packed-refs也很有用

$ cat packed-refs 
# pack-refs with: peeled fully-peeled 
3c1d4742e649fe9c8aed8c2817fe3e1f3364f298 refs/remotes/origin/aoo/aw080
e87c8b7922e9a73e0abb7f9a7a47c9ac3374a826 refs/remotes/origin/aoo/trunk
b70fdffb041c12f124dcc0822b61bf3450e53137 refs/remotes/origin/distro/capgemini/cg-4.1
5dbc3f1754809b9489faaf380b1a4bdbcfbb6205 refs/remotes/origin/distro/cib/libreoffice-5-0
cfdbc96ca47d68d6785fd21829a8d61f49d6e591 refs/remotes/origin/distro/cib/libreoffice-5-1
5189c8c47461ef09739086e55512fc6a10245273 refs/remotes/origin/distro/cib/libreoffice-5-2
3bee5917569ca8e6ee3b086458f5b1a917b88ca1 refs/remotes/origin/distro/cib/libreoffice-5-3
92fbe703f9ca480d3a2b8610d87e991c729edf77 refs/remotes/origin/distro/cib/libreoffice-5-4
05c0a5df66cc69d75280f05b804cf82f3387d42b refs/remotes/origin/distro/cib/libreoffice-6-0
7fe193e759b24b90852e6e327115b77114d7b119 refs/remotes/origin/distro/cib/libreoffice-6-1
8187f7aa413e7ef7b377eea2b057d336bf256867 refs/remotes/origin/distro/collabora/cd-5.3
7a6b608591e21ef61dc05cff9fc58da531035755 refs/remotes/origin/distro/collabora/cd-5.3-3.1
....

毫无疑问,这留下的问题多于答案,但我认为它可以开始帮助你回答你自己的问题,即什么是什么。

最新更新