【问题标题】:Why do GitHub and the git command line give different results for merge status & commits ahead/behind?为什么 GitHub 和 git 命令行为合并状态和提前/后面提交给出不同的结果?
【发布时间】:2023-03-14 15:26:01
【问题描述】:

当我跑步时

git branch --no-merged

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

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

这个分支是 master 后面的 1291 次提交。

当我转到 GitHub 的拉取请求界面时,我得到:

没有什么可比较的。

ma​​ster 是最新的,包含来自 dcxl 的所有提交。

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

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

当我运行它时,我得到:

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

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

现在,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

还是不一样。

我还有其他 repos,其中 git rev-list 的输出与 GitHub 的输出完全匹配。而这个特定的 repo,包括分支,都是从 Mercurial 迁移过来的,所以历史上可能会有各种各样的恶作剧。但我很确定 GitHub 是对的,在这里,这个分支中没有任何需要合并的东西。

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

【问题讨论】:

  • 在链接答案下方的评论中,有人建议运行git rev-list --left-right --count origin/master...@ | cut -f1 来获得幕后,你试过了吗?它输出什么?

标签: git github


【解决方案1】:

我不完全确定你为什么会得到你得到的结果,但这显然与你有 你自己的 分支这一事实有关。我只是自己克隆了存储库,这就是我得到的:

$ 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 clonegit checkout master 结束,它使用origin/master 创建了我的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 更新当前哈希为 Hold 的分支名称,使其新哈希为 Hnew,Git 将检查Hold 是否是 Hnew 的祖先。如果是这样,那么该更新就是快进。如果不是,则请求的更新是非快进的:它可能仍然被允许(取决于您请求它的方式),但进行更改可能会丢失提交。

如果您在某个分支上并运行 git merge <em>commit-specifier</em>,对于任何有效的提交说明符 - 请参阅 the gitrevisions documentation 了解所有拼写提交的方式 - Git 将检查更改是否可以作为快进完成.如果是这样,Git 将更新您的索引和工作树并对分支名称进行快进。这根本不是合并!但是如果操作不能以快进的方式完成,Git 将执行合并过程,如果成功,则进行 merge commit 以记住先前的当前提交和之前的提交你刚刚合并。这是一个真正的合并。

您自己的分支名称(如dcxl)因此可能与origin/<em>name</em> 远程跟踪名称不对应,因为您没有执行快进,或者您执行的合并不是快进。或者你甚至可能有这些的组合:一些合并和/或快进完成,但你的分支名称仍然在另一个后面。

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

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

【讨论】:

  • 就是这样。如果我运行git rev-list --left-right --count origin/dcxl...master,我会得到0 1291
猜你喜欢
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
相关资源
最近更新 更多