我有一个线性历史,上面有两个分支,dev
和 master
。 master
总是可以快速转发到 dev
,并且没有其他分支。我想从 git rev-parse
获取 dev
和 master
之间的所有提交。
例如,我的历史是这样的(来自 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
这样的陶瓷命令,但我愿意接受任何运行良好的解决方案。
最佳答案
作为Leon noted in a comment ,答案是使用git rev-list
.
Git 的修订处理代码是……复杂的。但是您可以使用一个很好的心智模型:
有版本说明符,列在the
gitrevisions
documentation中.除了范围符号(X..Y
和X...Y
以及一些更深奥的说明符,如<rev>^@
),它们指定一个特定的对象,通常是一个提交。但是,指向带注释标签的标签名称解析为其带注释的标签对象,除非您使用gitrevisions
样式后缀强制 Git 将这些“剥离”到提交,甚至是树或 blob。rev-parse
命令与修订说明符一起使用(加上所有其他的好处,例如解析 shell 脚本的参数,或向您显示顶级目录的位置,或测试--bare
存储库)。但是你可以选择其中一个“有祖先”,我称之为。这仅对提交或 Git 可以解析为提交的标记对象有意义。选择具有祖先的提交会让您获得该提交及其父提交(通常只有一个提交,但如果是 merge 则更多),以及那些父提交的 parent ——提交的祖 parent ——以及他们的 parent 等等一直持续下去,直到您在根提交(没有 parent 的提交)处遇到死胡同。
rev-list
命令是 selection-with-ancestry 的作用。事实上,它总是这样做,除非您添加--no-walk
论据。
当您使用像 X..Y
这样的范围说明符时或 X...Y
, git rev-parse
尽最大努力将这些变成大致等效的前缀为 ^
的个人提交如果需要的话。这实际上丢失了一些信息:你真的无法分辨 X...Y
来自 X Y ^$(git merge-base X Y)
,例如,1 这意味着您无法确定哪个是左侧修订说明符。但总的来说,如果你正在做一些需要 rev-list
的事情-style 解析你将只使用 git rev-list
无论如何,不必担心;和 git rev-list
有更多的标记,例如前缀 -
对于 --boundary
.
(rev-list
命令也能够公开树和对象 ID,但你必须给它额外的标志才能实现它。它被如此多的 Git 命令使用,以至于 git rev-list
's documentation 非常长,而且充满了特定选项,如 --bisect
。尽管如此,需要意识到的一件有用的事情是 git log
和 git rev-list
几乎是相同的命令,具有不同的默认输出格式。还有一些其他细微差别,但它们使用相同的源代码做大部分相同的事情,两个前端是从一个 builtin/log.c
文件构建的。)
1大多数命令不需要,但是git rev-list
本身就是,git diff
做。另外,如果有多个 merge 基础,X...Y
将重新解析为 X(无帽子前缀)的 ID 加上 Y(没有帽子前缀)的 ID 加上所有 的 ID merge 基础(都带有帽子前缀),因为这里的想法是选择所有可从 X 或 Y 到达的提交,但不是从两者中选择,因此排除所有它们 merge 基础和所有早期提交。
关于git - 使用 git rev-parse 获取同一分支中的提交范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38357020/