如何将日志限制为给定提交的所有后代? [英] How can I limit the log to all the descendants of a given commit?
问题描述
给出历史记录
X-Y <- feature
/
A-B-C-D-E <- master
我想获取给定提交的后代.一种解决方案似乎是:
I want to get the descendants of a given commit. One solution seems to be:
git log --all --ancestry-path <ref>^!
但是,这种行为有点奇怪:
However, the behaviour is a bit strange:
- 当
<rev>
为C
时,结果为CDEXY
-
<rev>
为D
或X
时,结果为DEXY
(很奇怪!) - 当
<rev>
为E
时,结果为E
- when
<rev>
isC
, the result isCDEXY
- when
<rev>
isD
orX
, the result isDEXY
(weird!) - when
<rev>
isE
, the result isE
我的理解是该命令无法获取<rev>
的所有子级;相反,它将获取parent-of(ref)的所有子代.我说的对吗?
My understanding is that the command does not get all children of <rev>
; instead, it gets all children of parent-of(ref). Am I right?
这是不直观的,容易出错的,并且坦率地说,很烦人.为了将日志限制为给定提交的后代,应该如何运行命令.
This is unintuitive, error prone, and, quite frankly, irritating. How command should I run instead, in order to limit the log to the descendants of a given commit.
推荐答案
如何将日志限制为给定修订版的所有后代
据我所知,没有内置的Git命令可以做到这一点.但是,您快要到了.试试
How to limit the log to all the descendants of a given revision
As far as I know, there is no built-in Git command to do that. However, you're almost there. Try
git log --all --ancestry-path ^<rev>
相反.那应该将日志限制为<rev>
的后代;请注意,严格来讲,<rev>
本身不是子代,因此不会列出.
instead. That should limit the log to the descendants of <rev>
; note that, strictly speaking, <rev>
is not a child of itself, so it doesn't get listed.
例如,在我的玩具仓库中(我复制了您的玩具;请参见答案的底部),
For instance, in my toy repo (I replicated yours; see the bottom of my answer),
git log --all --ancestry-path ^D
限制日志提交E
,并且
git log --all --ancestry-path ^X
限制日志提交Y
.
我的理解是该命令无法获取
<rev>
的所有子级;相反,它将获取parent-of(ref)的所有子代.我说的对吗?
My understanding is that the command does not get all children of
<rev>
; instead, it gets all children of parent-of(ref). Am I right?
是;您的底部提交减少了一个.
因为在您的示例中,提交D
和X
是对称的,所以我们只关注提交D
并解构命令
Because, in your example, commits D
and X
are symmetric, let's just focus on commit D
and deconstruct the command
git log --all --ancestry-path D^!
根据相关的Git手册页,
后缀
^
后跟带有感叹号的情况与提交<rev>
相同,然后给其所有父项加上^
前缀以排除它们(及其祖先).
A suffix
^
followed by an exclamation mark is the same as giving commit<rev>
and then all its parents prefixed with^
to exclude them (and their ancestors).
此外,根据 git-log
手册页,
Furthermore, according to the git-log
man page,
--all
假装ref/中的所有ref都在命令行中列为<commit>
.
Pretend as if all the refs in refs/ are listed on the command line as <commit>
.
因此,就您而言
git log --all --ancestry-path D^!
等效于
git log --ancestry-path D ^C feature master
此外,由于从master
可以访问D
,因此后一个命令减少为
Moreover, because D
is reachable from master
, the latter command reduces to
git log --ancestry-path ^C feature master
这将提供从feature
或主服务器可访问的所有提交的日志,但不包括C
或其任何祖先,您将获得D
,E
,X
和
This gives a log of all the commits reachable from either feature
or master, but excluding C
or any of its ancestors, and you get commits D
, E
, X
, and Y
.
如您所见,您的下一次提交被一次关闭.您真正想要运行的东西
As you can see, your bottom commit is off by one. What you really want to run
git log --ancestry-path ^D feature master
与
git log --all --ancestry-path ^D
测试
以下命令重新创建了玩具仓库:
Test
The following commands recreate your toy repo:
$ mkdir gittest
$ cd gittest/
$ git init
$ printf "A\n" > README
$ git add README
$ git commit -m "A"
$ printf "B\n" >> README
$ git commit -am "B"
$ printf "C\n" >> README
$ git commit -am "C"
$ git branch feature
$ printf "D\n" >> README
$ git commit -am "D"
$ printf "E\n" >> README
$ git commit -am "E"
$ git checkout feature
$ printf "X\n" >> README
$ git commit -am "X"
$ printf "Y\n" >> README
$ git commit -am "Y"
$ git log --all --oneline --graph --decorate
* e234427 (HEAD -> feature) Y
* cf98c6b X
| * b3d493a (master) E
| * e2bb266 D
|/
* dfe0267 C
* 0be7d42 B
* 674356e A
(请注意,提交D
和X
可以通过其SHA来引用,或更简单地说,可以分别通过master~
和feature~
来引用.)
(Note that commits D
and X
can be referred to by their SHAs, or more simply, by master~
and feature~
, respectively.)
您建议的命令(我添加了--oneline
标志,以减少输出)确实确实不将日志限制为给定提交的后代:
The command you suggested (I've added the --oneline
flag, to reduce the output) indeed does not limit the log to the descendants of the given commit:
# master~ = D
$ git log --all --ancestry-path --oneline master~^!
e234427 Y
cf98c6b X
b3d493a E
e2bb266 D
# feature~ == X
$ git log --all --ancestry-path --oneline feature~^!
e234427 Y
cf98c6b X
b3d493a E
e2bb266 D
但我建议这样做:
# master~ == D
$ git log --all --ancestry-path --oneline ^master~
b3d493a E
# feature~ == X
$ git log --all --ancestry-path --oneline ^feature~
e234427 Y
这篇关于如何将日志限制为给定提交的所有后代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!