git status vs fetch(或pull):如何知道“最新”的含义(不做任何改动)

时间:2016-06-08 06:10:15

标签: git

我做了git status并且说了 Your branch is up-to-date with 'origin/master'.

但是无论如何我做了git pull然后突然说了 14 files changed, ...

我觉得自己被骗了。我怀疑git没有坏掉。这必须意味着我不明白。

我做了一些阅读herehere并了解了两种非破坏性的方式来询问我是否最新

git status -uno

git fetch --dry-run

由于fetchpull的一部分,我认为这两者与前两者的做法不同。

让我感到困惑的是,我认为'最新'的意思是:“嘿,我们比较了这个存储库的两个副本(主分支),它们是相同的”

好的,但如果我可以用两种不同的方式提出问题并获得两个不同的答案,那么当每个问题都是关于比较两个不同的副本时,那么这是不是意味着必须至少有三个存储库副本? / p>

如:

  

A == B!= C

我知道有一个主人的远程副本 我知道我的本地副本

第三件事是什么?

2 个答案:

答案 0 :(得分:3)

当Git说Your branch is up-to-date with 'origin/master'时,它会将您的本地master分支与名为origin/master远程跟踪分支进行比较。此跟踪分支也存在于本地,是更新本地分支时实际使用的分支。当您执行git fetch时,所有远程跟踪分支都会更新。

您的本地master分支是跟踪分支的最新分支,但这并不意味着本地分支与存储库中的实际master分支是最新的。如果您在初次致电git fetch后完成了git status,那么您会看到一条消息,指出您当地的master分支机构是"背后" origin/master。执行git pull表示更新跟踪分支origin/master,然后将其合并到您的本地分支中以同步所有内容。

这是一个简单的图表,显示了从远程到本地分支的信息流:

remote master (repo) --> origin/master (local tracking branch) --> master (local branch)

答案 1 :(得分:2)

要向Tim Biegeleisen's answer添加一点 1 git status可以通过执行两个差异加上来进行比较当前HEAD到其上游。

这是完整的(... ish)图片。

鉴于远程存储库 R git fetchR上看到的每个分支复制 - 您可以通过运行git ls-remote R来查看它所看到的内容并重命名他们在这个过程中。对于分支 B1 B2 B3 ,您的Git会创建或更新远程跟踪分支 R / B1 R / B2 R / B3 。 (更确切地说,这些是名称以refs/remotes/开头的引用,然后继续命名相同的远程 R ,例如origin/,然后是分支名称。这保证这些引用永远不会与您自己的本地分支冲突,这些分支以refs/heads/开头:您的主人是refs/heads/master,而从远程origin复制的主人是refs/remotes/origin/master

(你的Git也可能会带来标签,具体取决于你给git fetch的标志。默认情况稍微复杂一点:它为带来分支的任何提交带来了标签。{{1}它完全跳过标签,并且--no-tags它会带来所有标签。标签与分支不同,没有特殊的每个远程名称空间:标签--tags实际上是T1,并且如果你的Git从远程 R 中带来了一个标记refs/tags/T1,它只是将它命名为T2。如果两个标记冲突,你的Git默认忽略额外的一个,即,如果你已经有一个refs/tags/T2,你的Git在场上放弃他们的 T2 2

为了引入这些分支(可能还有标记),你的Git必须带来它们所指向的提交(和任何其他对象),正如你将在同一个{{{1}中看到的SHA-1哈希所标识的那样。 1}}输出。要获得提交,您的Git必须获取该提交对象指向的任何树和blob。因此,你的Git和他们的Git会进行对话,导致对象计数和压缩,等等你看到:你的Git已经有了一些对象和你的对象,他们只是努力看看你有什么共同点,以确定最好的对象给你那些你还没有的人。

所有这些对象都会插入到您的存储库中。此时,远程跟踪分支(例如T2)会指向它们。如果您现在运行git ls-remote,它可以完全在本地运行。

让我们说你自己origin/master。在这种情况下,您的git status引用只包含字符串master 3 这实际上是 Git知道您在分支{{ 1}}。同时,Git在HEAD下存储了一些额外数据,用于记录您的本地ref: refs/heads/master master(真.git/config; Git只是缩写很多)作为其上游

因此,master发现您在origin/master并且还在查找refs/remotes/origin/master。这两个名称 - git statusmaster - 指向两个提交ID。那些提交ID可以是相同的,也可以是不同的。如果它们相同,则两个分支同步。如果它们不同,则两个分支不同。一个可能包含比另一个更多的提交 - 因此一个严格提前,另一个严格落后 - 或者它们可能在两个分支上都有一些不同的提交,以及一些两者都相同的提交。

(这就是Git&#39的术语出现故障:"分支"意思是"分支名称",如origin/master ?或者它是否意味着"所有提交的集合可以通过从分支机构的最尖端提交开始并通过历史记录来回复#34;?答案是它意味着两者,我们应该弄清楚要使用哪种含义。)

要获得refs/heads/master和/或refs/remotes/origin/master次,master使用ahead 3

behind 5

这个双点语法意味着"找到从右边的标识符可到达的所有提交的集合,并从左边的标识符中减去可以访问的所有提交的集合"。例如,假设git status严格地位于git rev-list --count之前。我们可以像这样绘制提交链:

git rev-list --count origin/master..master
git rev-list --count master..origin/master

此处master上的一个提交不在origin/master上。 ... <- o <- o <- o <-- origin/master \ o <-- master 上的所有提交都在两个分支上:本地分支和远程跟踪分支。但是master上有一个提交不在origin/master上。

origin/master获得新提交时,这些新提交通常会指向现有提交。因此,如果masterorigin/master上选择了一个新提交,则图片会更改:

git fetch

现在两个分支都没有严格落后,你可能想要合并或改变你的工作。

同时,git fetch 比较:

  • 您的origin/master提交
  • 的索引/登台区域
  • 您的工作树到您的临时区域

(单个,可分辨的)索引包含将进入 next 提交的所有文件的集合。当您... <- o <- o <- o <- o <-- origin/master \ o <-- master 现有文件的新内容时,这将替换暂存区域中的现有文件。 (严格来说,索引只包含哈希,加上文件路径等必要的东西,加上一堆缓存信息,以加快git statusHEAD git add步骤实际上将文件复制到存储库中,在git status时计算其散列,并将新散列存储到索引中。)添加一个全新的文件会添加一个新条目,并删除git commit的现有文件会添加一个特殊的&#34; erase&#34;或&#34;白色&#34;输入,以便Git知道不将该文件放入 next 提交。

add显示提交的内容时,它会通过将索引与add进行区分来实现。

git rm向您显示 时,

/ p>

1 好的,很多。

2 在1.8.4左右版本的Git中的一个错误中,只要标签以快进方式移动,标签就会发生变化,这与默认情况下应用的规则相同git status。我认为这不会发生在HEAD上。

3 git status是一个引用,就像git pushfetch一样,但有一些特殊处理。特别是,HEAD通常是间接引用,具有refs/heads/master前缀内容。虽然任何引用都可以是间接引用,但refs/remotes/origin/master是唯一有用的间接引用,至少目前(Git版本2.8.x)。此外,唯一有用的间接值是常规的本地分支。当HEAD包含本地分支的名称时,ref:表示您是&#34; on&#34;那个分支。

通过SHA-1哈希ID检查提交,或使用HEAD,将原始ID放入HEAD。在这种情况下,git status声称您不在任何分支机构。事实上,你在(单个)匿名分支上:你像往常一样进入存储库的新提交,但只有特殊名称--detach知道,如果你查看其他一些分支,ID那些提交变得有些难以检索。 (它们仍然存储在HEAD的reflog中,直到这些reflog条目到期;在此之后,它们有资格被git status垃圾收集。)