为什么GitHub和git命令行为合并状态给出不同的结果并在前面/后面进行提交?

时间:2018-07-12 19:12:21

标签: git github

我跑步时

git branch --no-merged

this repo上,第一个列出的分支是dcxl

但是当我在GitHub中查看分支时,我看到的只是

  

此分支在master后面提交了1291。

当我进入GitHub的请求请求界面时,我得到:

  

没有什么可比较的。

     

主控是最新的,并且来自dcxl的所有提交。

根据this answer,查看提交的方式是向前/向后

git rev-list --left-right --count [BRANCH]...master

运行此命令时,我得到:

$ git rev-list --left-right --count master...dcxl
426     1717

我将其读为“分支dcxl在426之前提交,在1717在master后面提交。”

现在,1717-426 = 1291,所以git rev-list输出与GitHub告诉我的内容之间显然存在某种关系,但是GitHub似乎以某种方式识别了这426个“预先”提交与1717后面的426个提交”以git rev-list不会提交的方式提交。

从某些答案中,我不确定哪个找到了--no-merges选项,并尝试了这样做,以防合并提交有所不同:

$ git rev-list --left-right --count --no-merges dcxl...master
396     1610

还是不一样。

我还有其他存储库,其中git rev-list的输出与GitHub的输出完全匹配。而且这个特定的仓库(包括分支机构)是从Mercurial迁移而来的,因此历史上可能存在各种各样的恶作剧。但是我很确定GitHub是正确的,这里,该分支中没有任何需要合并的东西。

但是如何从命令行检查呢?为什么我得到的数字不同?要获得GitHub给我的相同数字,我需要什么命令/选项?

1 个答案:

答案 0 :(得分:2)

我不确定您为什么要获得结果,但显然与您拥有自己的分支有关。我只是自己克隆了存储库,这就是我得到的:

$ git clone git://github.com/CDLUC3/mrt-dashboard
Cloning into 'mrt-dashboard'...
remote: Counting objects: 23264, done.
remote: Compressing objects: 100% (142/142), done.
remote: Total 23264 (delta 103), reused 127 (delta 56), pack-reused 23066
Receiving objects: 100% (23264/23264), 121.78 MiB | 3.51 MiB/s, done.
Resolving deltas: 100% (9203/9203), done.
$ cd mrt-dashboard/
$ git rev-list --left-right --count origin/dcxl...origin/master
0       1291

请注意,我没有名为dcxl的分支。我确实有(我自己的)master,因为我的git clone的最后一个操作是git checkout master,该操作使用master创建了origin/master,因此它们都指向相同的提交:

$ git rev-parse master origin/master
4c8616fe9b6eb3d3ea113c07ab307cfb78247c5e
4c8616fe9b6eb3d3ea113c07ab307cfb78247c5e

您显然必须拥有自己的dcxl,该指向其他提交,而不是origin/dcxl指向的提交:

$ git rev-parse origin/dcxl
f866dd35916bc7b8154441dce53c76d20b166c37

您自己的存储库可能有很多与另一存储库不同步的方式

请记住,每个名称都是一些Git哈希ID的易于理解的名称。分支名称具有一些特殊功能,包括以下两个:

  • 他们只指向 commit 对象,并且
  • Git知道可以使用快进操作“移动”分支名称。

origin/dcxl之类的远程跟踪名称与分支名称共享这些功能。

后者的意思是,如果您要求Git更新当前哈希为H old 的分支名称,使其新哈希为H new ,则Git将检查H old 是否是H new 的祖先。如果是这样,则该更新是快速的。如果不是,则请求的更新是非快速的:仍然可以允许(取决于您的请求方式),但是进行更改可能会丢失提交。

如果您在某个分支上并运行git merge commit-specifier,则对于任何有效的提交说明符-有关拼写提交的所有方法,请参见the gitrevisions documentation-Git将检查是否可以按如下方式进行更改快进。如果是这样,Git将更新您的索引和工作树,并对分支名称进行快进。这根本不是合并!但是,如果无法快速完成该操作,则Git将经历合并过程,如果成功,则进行 merge commit 以便同时记住先前的提交和您刚刚合并。这是真正的合并。

因此,您自己的分支名称(例如dcxl可能与origin/name远程跟踪名称不对应,这可能是因为您没有进行快进,或者是因为合并不是快速的-向前。或者,您甚至可以结合使用这些方法:完成一些合并和/或快速转发,但是您的分支名称保留在另一个名称之后。

或者,另外,其他Git存储库可能以非快进的方式粗暴地推销了其分支名称。在这种情况下,您的本地分支上的提交可能无法从远程跟踪名称的当前值访问。

(当然,首先运行git fetch很重要。这会更新您自己的远程跟踪名称,以记住分支名称的当前值,如GitHub上Git存储库中存储的那样。您此时,您将看到哪些远程跟踪名称正在快速转发,而哪些正在强制更新,尽管git fetch实际上以三种方式(!)显示了这一点,这还是有些微妙的。 )