列出 git 中 2 个提交哈希之间的提交

Posted

技术标签:

【中文标题】列出 git 中 2 个提交哈希之间的提交【英文标题】:List commits between 2 commit hashes in git 【发布时间】:2013-09-11 20:35:45 【问题描述】:

我知道这里有非常相似的问题,但它们并没有解决我的问题。 可能有些地方我不太理解。

这是 Fitnesse (https://github.com/unclebob/fitnesse/) 提交历史的一部分:

* | | | | | | | | | | | | | | | fa86be8 Avoid possible issue when using CachingPage under heavy memory load.
|/ / / / / / / / / / / / / / /  
* | | | | | | | | | | | | | |   7b4a07a Merge pull request #256 from barredijkstra/fitnesse_issue_250
|\ \ \ \ \ \ \ \ \ \ \ \ \ \ \  
| * | | | | | | | | | | | | | | ecf5891 Fixed test checking for OS specific exception message.
| * | | | | | | | | | | | | | | 082236e Added rendering of cause exceptions. Fix for unclebob/fitnesse#250
* | | | | | | | | | | | | | | |   a92b37f Merge pull request #243 from amolenaar/fix/243-hash-table-rendering

我想要 2 个提交哈希之间的提交列表。在这种特殊情况下,我想要ecf58917b4a07a 之间的提交,我希望结果是:

ecf5891
7b4a07a

到目前为止,我一直在使用git rev-list commit_hash_from_here^..commit_hash_up_to_here,它在线性历史上运行良好。但是,在这种情况下,我得到了更多的提交。

我已经尝试过了,它按预期工作:

git log --since='<date ecf5891>' --until='<date 7b4a07a>'

(我已经手动搜索了这两个日期)。

一种可能的解决方案是获取 2 个日期并这样做,但我认为应该有更好的方法。

编辑: 7b4a07a 父母是 ecf5891a92b37f。到目前为止,如果我想从ecf5891 转到7b4a07a,解决方案工作正常,但如果我想从a92b37f 转到7b4a07a,我想得到:

7b4a07a
ecf5891
082236e
a92b37f

但我没有收到a92b37f

【问题讨论】:

【参考方案1】:

我认为您正在寻找--ancestry-path,就您而言:

git rev-list --ancestry-path 7b4a07a..ecf5891

【讨论】:

--ancestry-path 是我的票。最后,我以这种方式使用了它:git log --oneline --ancestry-path commit1~1..commit2,以便准确查看我拥有的两个提交哈希之间的所有内容。谢谢! commit 1 需要是旧的 commit,commit 2 是新的 commit 才能使这些命令起作用【参考方案2】:

当涉及到 git 提交时,“Between”是一个有点模糊的概念。

您在上面显示的文本以及图形输出的 sn-p 说明了为什么 from^..to 产生的不仅仅是这两个提交:to 部分是一个合并提交。

符号 A..B 实际上只是 B ^A 的简写。也就是说,“从 B 开始并向后工作的所有内容,减去从 A 开始并向后工作的所有内容”。但是 B 是一个合并提交,所以“一切从那里开始并向后工作”使用双亲

这里7b4a07a 的第一个父级是a92b37f(不在您上面的[原始] sn-p 中,但我克隆了链接的存储库并找到了它)。不过,我们可以象征性地提及它,我将在下面提及。 7b4a07a 的第二个父级是 ecf5891,即您感兴趣的“来自”部分。

当您要求时:

ecf5891^..7b4a07a

意思是:

7b4a07a ^ecf5891^

等同于:

7b4a07a ^082236e

这会让你成为合并的父母,然后从082236e 中删除所有内容。您需要从7b4a07a^(第一个父级)和后面删除所有内容:

git rev-list 7b4a07a ^ecf5891^ ^7b4a07a^
git log --oneline 7b4a07a ^ecf5891^ ^7b4a07a^

不过,一般来说,您必须弄清楚要切断哪些后代行。

编辑:您可以坚持使用 A..B 表示法,但您确实需要添加额外的“排除”。所以jthill's answer 也可以,只要你把帽子移到前面。


重新编辑(“如果我想从 a92b37f 转到 7b4a07a”):我们又回到了“介于”这个概念上的问题。哪些提交是“之间”?从a92b37f7b4a07a 有一条直线,因为a92b37f 是合并提交7b4a07a 的两个父级之一。因此,根据较早的逻辑(“直接在祖先线上提交”,也许是“包容性”),这将只是这两个提交中的一个,或者可能两者兼而有之。但是你说你想要两个在任何祖先意义上都与a92b37f 完全无关的提交。 为什么你想要这两个特定的提交?是什么让082236e“有趣”和082236e^,它的父级“无趣”?

【讨论】:

好的,我理解你所说的“一路回来,但这适用于 2 位父母”。然后,你做我之前做的事情,并通过^7b4a07a^^a92b37f 砍掉额外的父级部分。你怎么知道7b4a07a^ 将成为“另一个”父母而不是ecf5891?我是在脚本中执行此操作的,因此无法手动查找。 “是的,问题来了”——哈姆雷特。仅从提交本身就无法先验知道要切断合并的哪个父级。您必须提供(也许很多)更多背景信息。 现在我想要按时间顺序提交,“之间”的概念是:在时间图中查找提交 A 和 B,它们之间的所有提交,包括 A 和 B。也许它没有多大意义,我想得太svn方式了。到目前为止,解决方案是最简单和最丑陋的:获取所有提交哈希,搜索 A 并添加到列表,直到找到 B。无论如何,谢谢你,你已经清除了一些东西,让我想如果按时间顺序的方式是什么我在找。 或者,也许它确实有意义,而您想要 限制 --since--until (或 --min-age--max-age 做同样的事情事物)。 (注意,这些查看的是“提交者”日期而不是“作者”日期,即提交补丁的时间与编写补丁的时间。)但是,是的,这就是问题,当历史是非线性?【参考方案3】:

首先确定您需要的相关 2 个提交哈希,以便通过使用获取它们之间的提交哈希列表

git log --oneline

然后您可以选择相关的两个提交哈希,并通过使用找到它们之间的提交哈希

git log <commit hash 1>..<commit hash 2> --oneline | cut -d " " -f 1

【讨论】:

你测试了这个答案吗?我的not producing expected results。 我需要做以下事情:git log --oneline hashone..hashtwo 有趣的是,“from”提交必须比“to”提交更早,否则它不起作用。 为什么需要 --online 选项?! with --online 和 without 有什么区别?【参考方案4】:

添加 ^7b4a07a~ 以排除合并的第一个父级可访问的所有内容。您只是排除了从其第二个父级可访问的内容。

【讨论】:

各种错别字,你需要前面的^(或--not 我应该在哪里添加该部分?完整的生产线如何? 将它添加到规范的其余部分,只是另一个参数。 @torek: :-P 哟。谢谢。 好的,到目前为止有效。但是,在我在编辑中提供的情况下它不起作用。 您拥有执行此操作所需的所有工具。 git help revisions 将引导您通过所有方式指定您想要或不想要哪些修订。要理解的是它在描述中所说的内容:在提交集上工作的命令使用“可访问自”和“不可访问自”规范。现在你需要的只是时间和一些实验和玩耍。

以上是关于列出 git 中 2 个提交哈希之间的提交的主要内容,如果未能解决你的问题,请参考以下文章

列出两个日期之间对 master 分支的 git 提交

Git Tag 列表,显示提交 sha1 哈希

通过 Git 中的 SHA 哈希恢复提交? [复制]

在 Git 中,如何将当前提交哈希写入同一提交中的文件

如何在 2 次提交之间创建一个 git diff/diff-tree/archive 与此时的文件版本(不是头)

GIT 在特定提交之前获取提交哈希