检索 Git 中特定提交的子提交列表

问题描述 投票:0回答:3

我想知道是否有一种有效的方法来检索给定提交的子项。 虽然在Referencing the child of a commit in Git中讨论了一种方法,但效率非常低。

我认为这在 Git 中是一件简单的事情,但显然事实并非如此。

git
3个回答
37
投票

git rev-list
可以显示子项,但这些子项必须可以从您提供的提交中访问。假设您想显示可以从存储库中的所有分支访问的所有子级,您可以使用类似的东西

git rev-list --all --not $COMMIT^@ --children | grep "^$COMMIT"

这应该输出一行,如下所示

$COMMIT $child1 $child2 $child3 ...

为了方便起见,您可以通过将以下行添加到 ~/.gitconfig 的 [alias] 部分,将命令转换为 git 别名:

children = "!f() { git rev-list --all --not $1^@ --children | grep $(git rev-parse $1); }; f" # reachable children of a ref

语法

$COMMIT^@
可能会令人困惑,所以我会解释一下。希望
$COMMIT
是不言自明的。然后是
^@
,它扩展到引用提交的所有父级。所以
$COMMIT^@
的意思是“
$COMMIT
的所有父母”。由于它遵循
--not
标志,因此指示
rev-list
在到达
$COMMIT
的任何父级后停止处理。这基本上只是一种优化,因为从
$COMMIT
可以到达的任何提交都不可能是子提交。


注意:此答案的先前版本说的是

tail -1
而不是
grep "^$COMMIT"
。这可能在一个简单的测试存储库中起作用(这就是我最初这么说的原因),但是如果您有任何不包含
$COMMIT
的分支,则不能保证 git rev-list 最后会发出
$COMMIT


3
投票

我使用以下别名(基于 @Lily Ballard 的回答

# Get all children of current or specified commit-ish
children = "!bash -c 'c=${1:-HEAD}; set -- $(git rev-list --all --not \"$c\"^@ --children | grep $(git rev-parse \"$c\") ); shift; echo $*' -"
  • 无参数 - 给出
    HEAD
  • 的所有子代
  • 使用
    commit-ish
    - 给出该对象的所有子对象

0
投票

我也开始使用@Lily Ballard 的答案(非常感谢莉莉和其他编辑该答案的人,它效果很好!)。但从那里开始之后,我想出了一种稍微不同的方法来做对我来说效果更好(运行得更快)的事情。这是您在 ~/.gitconfig 的 [alias] 部分中放入的内容:

children = "!f() { git branch --contains "$1" --format='%(refname:short)' | git rev-list --not "$1^@" --children --stdin | grep -F "$(git rev-parse $1)" ; }; f"

这是做什么的:

  1. 该函数的第一部分是一个
    git branch
    命令,它表示“查找作为输入引用的后代的所有分支”。
  2. 这些分支名称通过管道作为输入发送到
    git rev-list
    命令。此命令与 @Lily Ballard 的答案中的命令非常相似,只是它不使用
    --all
    ,这使得
    git rev-list
    考虑整个存储库中的所有提交。相反,它通过标准输入从第一个命令获取分支名称,并且仅考虑作为这些分支的祖先的提交。
  3. 然后它将这些结果通过管道传输到与 @Lily Ballard 的答案中相同的 grep 命令。

在我个人的测试中,这个函数的运行速度比 @Lily Ballard 的答案中的函数快约 8 倍(约 0.07 秒而不是约 0.57 秒)。但显然,速度差异将完全取决于您的存储库的总大小以及您感兴趣的提交处子树的大小/复杂性。

© www.soinside.com 2019 - 2024. All rights reserved.