使用git rev-parse获取同一分支中的提交范围

时间:2016-07-13 16:23:04

标签: git

我有一个有两个分支的线性历史记录,devmastermaster总是可以快进dev,而且没有其他分支。我想从dev获取mastergit rev-parse之间的所有提交。

例如,我的历史记录如下(来自git log --graph --decorate --oneline --branches):

* 693dc30 (HEAD, dev) E
* d650d35 D
* 1c4e641 C
* b27ea83 (master) B
* 95fe748 A
...

我目前正在尝试致电

git rev-parse master..dev

并希望得到像

这样的东西
693dc30...
d650d35...
1c4e641...

相反,我得到

693dc30...
b27ea83...
^b27ea83...

如何获取指定选择之间的完整提交列表,以及如何正确解释我得到的git rev-parse的结果?

我使用的是Git 1.7.1版。我更喜欢在这个应用程序中使用像rev-parse这样的低级命令,而不是log之类的瓷器,但我对任何运行良好的解决方案持开放态度。

1 个答案:

答案 0 :(得分:4)

作为Leon noted in a comment,答案是使用git rev-list

Git的修订处理代码很复杂。但是你可以使用一个很好的心理模型:

  • 修订说明符,列在the gitrevisions documentation中。除了范围符号(X..YX...Y以及一些更深奥的说明符(如<rev>^@)之外,这些符号指定了一个特定的对象,通常是提交。指向带注释标记的标记名称解析为其带注释标记的对象,但除非使用gitrevisions样式后缀强制Git将这些标记“剥离”为提交,或者甚至是树木或斑点。

    rev-parse命令适用于修订说明符(加上所有其他好东西),例如解析shell脚本的参数,或显示顶级目录的位置,或测试{{1} } repository)。

  • 但是我可以选择其中一个“带有祖先”,我称之为。这只适用于提交,或者Git可以解析为提交的标记对象。选择带有祖先的提交会获得提交,并且其父提交(通常只提交一次,但如果是合并则提交更多),并且那些父提交'父级 - 提交的祖父母 - 和他们的父母等等永远在线,直到你遇到根提交的死胡同(没有父母的提交)。

    --bare命令是选择与祖先的关系。实际上,除非您向参数添加rev-list,否则始终会执行此操作。

当您使用--no-walkX..Y等范围说明符时,如果需要,X...Y会尽力将其转换为大致相等的单个提交,前缀为git rev-parse。这实际上丢失了一些信息:你无法从^真正告诉X...Y,例如, 1 这意味着你无法确定哪个是左边的 - 侧修订说明符。但总的来说,如果你正在做一些需要X Y ^$(git merge-base X Y) - 样式解析的东西,你只需要使用rev-list而不必担心;并且git rev-list还有更多标记,例如git rev-list的前缀-

--boundary命令也能够公开树和对象ID,但是你必须给它额外的标志来实现它。很多Git命令都使用它git rev-list's documentation非常长并且充满了rev-list之类的特定选项。但要实现的一个有用的事情是,--bisectgit log几乎是相同的命令,具有不同的默认输出格式。其他微妙的差异,但他们使用相同的源代码来完成相同的事情,并且两个前端是从单个git rev-list文件构建的。)

1 大多数命令不需要,但builtin/log.c本身,git rev-list。此外,如果有多个合并基础,git diff将重新解析为 X 的ID(无帽子前缀)加上 Y 的ID(无帽子)前缀)加上所有合并库的ID(全部带帽子前缀),因为这里的想法是选择从 X Y可以到达的所有提交,但不是两者兼而有之,因此排除了所有合并基础和所有早期提交。