如何将日志限制为给定提交的所有后代? [英] How can I limit the log to all the descendants of a given commit?

查看:69
本文介绍了如何将日志限制为给定提交的所有后代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出历史记录

      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>DX时,结果为DEXY(很奇怪!)
  • <rev>E时,结果为E
  • when <rev> is C, the result is CDEXY
  • when <rev> is D or X, the result is DEXY (weird!)
  • when <rev> is E, the result is E

我的理解是该命令无法获取<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?

是;您的底部提交减少了一个.

因为在您的示例中,提交DX是对称的,所以我们只关注提交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或其任何祖先,您将获得DEX.

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

(请注意,提交DX可以通过其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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆