如何获取两个Git分支之间不同提交的列表?

10

我希望能够看到两个分支之间仅包含非公共提交的列表。

我该如何获得像这样的输出?

基本上是两个分支之间的git diff -y master new-feature 概要:

              master                               new-feature
-------------------------------------|--------------------------------------
xxx - Jan 1st 2018 - initial commit  | xxx - Jan 1st 2018 - initial commit
xxx - Feb 1st 2018 - fix a bug       | xxx - Feb 1st 2018 - fix a bug
                                     > xxx - Mar 1st 2018 - WIP almost done
xxx - Apr 1st 2018 - fix another bug | xxx - Apr 1st 2018 - fix another bug
xxx - May 1st 2018 - fix more bugs   | xxx - May 1st 2018 - fix more bugs
                                     > xxx - Jun 1st 2018 - Ready to merge!
xxx - Jul 1st 2018 - latest patches  < 
解决方案: 我不知道如何理解它,但我认为 git log --graph 可以完成这个任务,只是它的可视化效果非常混乱。
git log --left-right --graph --cherry-pick --oneline master

还是这个?

更好的选择是,git diff -y --suppress-common-lines master new-feature 这才是我真正想要的:

              master                               new-feature
-------------------------------------|--------------------------------------
                                     > xxx - Mar 1st 2018 - WIP almost done
                                     > xxx - Jun 1st 2018 - Ready to merge!
xxx - Jul 1st 2018 - latest patches  <

解决方案: 只使用Git可能无法实现,但是根据@torek的回答,你可以使用git rev-list,基本上可以实现:

git rev-list --left-right master...new-feature

>eb57618eed654685a7999da847628dc5eb27313f
>0da0196ab24542a1a1697b1c0c5efeef6d09e027
>9452f57d97e5fc86e773e7a9fca488b7a0d44a0c
<4fc12fe25a127f8f0dfddf7625c22656c7b2c7c1
<9c0058dcabacfc6560f4fbaf73ea55dd70d27036
>5117fcd041793898683f9469aac00337e9fadd8b

或者仅仅是这个?

更加关键的是,像 git diff --right-only master new-feature 这样的视图就可以完成工作:

     commits only in new-feature
-------------------------------------
xxx - Mar 1st 2018 - WIP almost done
xxx - Jun 1st 2018 - Ready to merge!

当然,这可以被反转以得到相反的观点git diff --right-only new-feature master

       commits only in master               
-------------------------------------
xxx - Jul 1st 2018 - latest patches 
解决方案:正如@brentjanderson指出的那样git log main..new-featuregit cherry -v main都可以实现这一功能。
git cherry -v main

+ c00335cd93898683f9469aafad8a8476227b117f WIP do things
+ f5c86e777d97e5f3e7a9fca488b79a0d44ac9452 WIP do more
+ 0ef6ddda576180196ab7b1c0c57eefe009e027dc Finished!

以及

git log master..new-feature --format="%h - %ad - %s" --date=format:'%b %d %Y'

c00335cd - Jan 01 2018 - WIP do things
f5c86e77 - Feb 01 2018 - WIP do more
0ef6ddda - Mar 01 2018 - Finished!

P.S. 我以前尝试过 git checkout new-feature; git log --left-right --graph --cherry-pick --oneline master,但是我无法理解输出的意义。事实上,仔细想想,我敢打赌把输出结果旋转90度,将其作为excitebike地图玩会很有趣。嗯...

3个回答

18

以下是一个没有花哨格式的基本变量:

git log master..new-feature

通过交换分支的顺序,您可以获取“左侧”或“右侧”的数据:

git log left-side-branch..right-side-branch

这也适用于其他引用(提交哈希、远程分支、标签)。

要获取您想要的完整日期格式:

git log master..new-feature --format="%h - %ad - %s" --date=format:'%b %d %Y'

由于strftime不支持序数日期(Mar 1st 2018Mar 01 2018),此命令无法做到。如果这是硬性要求,建议编写批处理脚本。


并添加一些硬核 ANSI 转义和着色 https://dev59.com/Y2sz5IYBdhLWcg3wg4Cv#16735971 - coolaj86

5
我想看到两个分支之间唯一非共同提交的列表。
换句话说,这是从X和Y分支可达的提交集的对称差异在集合理论中的表现形式。
这种特定的集合分组非常有用,因此它被内置于Git修订解析器中,使用gitrevisions文档中描述的语法,使用三个点:X...Y
首先使用git rev-list --left-right master...new-feature。当使用对称差异符号并添加--left-right时,Git将列出提交记录以及一个标记:<(如果提交记录可从左侧的名称但不可从右侧的名称访问)或>(如果提交记录可从右侧的名称但不可从左侧的名称访问)。因此:
git rev-list --left-right master...new-feature

将会给你:

<aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd
>eeeeeeeeeeffffffffff00000000001111111111

例如,如果提交 aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd 存在于 master 分支中但不存在于 new-feature 分支中,而提交 eeeeeeeeeeffffffffff00000000001111111111 存在于 new-feature 分支中但不存在于 master 分支中。

(选项如 cherry-mark--left-only 等会修改或替换标记以指示哪些提交是补丁等效的(如果有),或省略左侧或右侧,或两者都省略。对于此情况,您不需要这些选项。)

git rev-list获取列表后,您可以按照自己的喜好重新格式化它。您可以在git log中使用这些选项,但通常最好先收集哈希ID,然后再处理格式,除非git log--pretty=format:...指令恰好符合您的需求(要了解,请参阅git log文档的PRETTY FORMATS部分)。

1
非常感谢。我希望我能够将多个答案标记为正确,因为每个答案都回答了问题的一部分,我认为在这三个答案之间,我已经掌握了所有需要的知识。 - coolaj86

2

我认为在你的new-feature分支上运行git cherry -v master应该可以解决右侧的问题。然后在主分支上执行相反操作以解决列表左侧的问题。


OOoooOooh!我喜欢那个。你知道我可以得到日期输出的任何方法吗? - coolaj86
我还没有接受这个(尚未),因为我想看看其他答案。 - coolaj86
我不确定如何获取日期。你可能可以通过脚本或其他方式将git loggit cherry结合起来,但我认为git cherry没有内置选项来输出日期。 - Tom Pridham
1
git cherry 是专门用于查找与其他范围中的提交不同或相同的可达当前分支的提交。它本质上与 git rev-list --right-only --cherry-mark A...Bgit rev-list --left-only --cherry-mark A...B 的结果相同,具体取决于您为 A 和 B 列出的名称,并默认使用 HEAD 作为其中一个名称。 (添加 <limit> 参数会将 ^<limit> 添加到 git rev-list,但通常使用 git cherry 更方便)。 - torek
以上内容的TL;DR摘要是:git cherry非常有用,但并不完全满足@CoolAJ86的要求。 - torek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接