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

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

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

Origin /master vs. remotes/ Origin /master

据我所知,master是一个本地分支,remotes/origin/master是一个远端分支。

但到底什么是起源/主宰?


当前回答

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

“remotes/origin/HEAD是默认的分支”是不正确的。

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

把HEAD看作你的工作区域。当你这样想的时候,'git checkout branchname'对于将你的工作区域文件更改为特定分支的文件是有意义的。您将分支文件“签出”到您的工作区域。对于所有实际目的来说,HEAD是你在工作区域可以看到的东西。

其他回答

从技术上讲,在你的Git回购中实际上根本没有任何“远程”的东西,只有本地名称,这些名称应该与另一个不同的回购上的名称对应。命名为origin/whatever的那些最初将与你克隆的回购上的那些匹配:

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

生成另一个回购的本地副本。在这个过程中,它会记录所有在那里的分支,并提交那些被引用的分支,并将它们以refs/remotes/origin/的名称粘贴到本地repo中。

Depending on how long you go before you git fetch or equivalent to update "my copy of what's some.where.out.there", they may change their branches around, create new ones, and delete some. When you do your git fetch (or git pull which is really fetch plus merge), your repo will make copies of their new work and change all the refs/remotes/origin/<name> entries as needed. It's that moment of fetching that makes everything match up (well, that, and the initial clone, and some cases of pushing too—basically whenever Git gets a chance to check—but see caveat below).

Git normally has you refer to your own refs/heads/<name> as just <name>, and the remote ones as origin/<name>, and it all just works because it's obvious which one is which. It's sometimes possible to create your own branch names that make it not obvious, but don't worry about that until it happens. :-) Just give Git the shortest name that makes it obvious, and it will go from there: origin/master is "where master was over there last time I checked", and master is "where master is over here based on what I have been doing". Run git fetch to update Git on "where master is over there" as needed.


注意:在1.8.4以上的Git版本中,Git获取有一些模式不会更新“master is over there”(更准确地说,这些模式不会更新任何远程跟踪分支)。运行git fetch origin,或者git fetch——all,甚至只是git fetch,都会更新。运行git fetch origin master则不会。不幸的是,这种“不更新”模式是由普通git拉取触发的。(这主要只是一个小麻烦,在Git 1.8.4及更高版本中得到了修复。)


嗯,有一种东西叫做“遥控器”。但那也是本地的!名称来源是Git称为“远程”的东西。它基本上只是克隆时使用的URL的一个简短名称。这也是origin/master中的原点的由来。名称origin/master称为远程跟踪分支,有时会缩写为“远程分支”,特别是在较老的或更非正式的文档中。

我认为这个git斜杠符号最好是通过查看你的。git文件夹来理解的。


例如,这里是我的.git的LibreOffice源代码库的一个略短的树。

在linux sudo中apt-get安装树是有用的。 在Windows中,我认为树命令可能仍然有效。

向下滚动,看看底部附近的refs(又名“references”):

$ 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可以保存一些远程,尽管目前我们只有origin在其中。 .git/refs/tags(在其他地方讨论)。

起源如此,是我们唯一遥远的。它保存了原点/主节点。


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

$ 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
  ...

列出的第一个分支(master)是唯一一个不是远程的分支。在这种情况下,我们有一个本地分支。这是我们开始自己工作的地方,用于我们自己的新分支和后续提交。

接下来,您可能有许多远程跟踪分支,我们这里就是这样做的。您知道这些是远程跟踪分支,因为它们的前缀是'remotes/'。这里显示的是远程命名的origin。

第二行是原点的当前分支指针。Remotes/origin: HEAD—指向—> master。这表明在远程存储库中,当前的分支是名为master的分支(不要与名为master的本地分支混淆)。 剩下的分支不在.git/refs/树中,而是在.git/ wrapped -refs中。

当我们获取git时,我们从远程存储库下载更改,到我们的远程跟踪存储库。

当我们进行git merge时,我们将这个本地远程跟踪存储库中的更改合并到我们的工作本地分支中,在这种情况下合并到我们的主分支中。

(当我们git pull时,我们在一次操作中完成这两个步骤。)


同样有趣的是,这些本地和远程uuid当前指向同一个节点(又名“提交”):

$ cat refs/heads/master                   # local         master
1ca409292272632f443733450313de5a82c54a9c

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

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

[local] master = [remote] origin master

最后,我认为看一下.git/ wrapped -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
....

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

给我这样的傻瓜的简短回答(从Torek那里偷来的):

origin/master是“上次我检查master在哪里” master指的是"根据我一直在做的事情,master在哪里"

复制一个远程存储库并运行git branch -a(显示git所知道的所有分支)。它可能看起来像这样:

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

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

git diff origin/master..master

你也可以把它称为remotes/origin/master:

git diff remotes/origin/master..master

这只是引用同一事物的两种不同方式(顺便说一句,这两个命令都表示“向我显示远程主分支和我的主分支之间的更改”)。

remotes/origin/HEAD是远程命名origin的默认分支。这让您可以简单地说origin而不是origin/master。

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

“remotes/origin/HEAD是默认的分支”是不正确的。

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

把HEAD看作你的工作区域。当你这样想的时候,'git checkout branchname'对于将你的工作区域文件更改为特定分支的文件是有意义的。您将分支文件“签出”到您的工作区域。对于所有实际目的来说,HEAD是你在工作区域可以看到的东西。