How can I limit the journal to all descendants of this commit?

Given the story

XY <- feature / ABCDE <- master 

I want to get the descendants of this commit. One solution is:

 git log --all --ancestry-path <ref>^! 

However, the behavior is a bit strange:

  • when <rev> is C , the result is CDEXY
  • when <rev> is D or X , the result is DEXY (weird!)
  • when <rev> is equal to E , the result is E

I understand that the team does not get all the children <rev> ; instead, he receives all the children of the parent (ref). I'm right?

This is unintuitive, error prone and, frankly, annoying. How to run the command instead to restrict the journal to the children of this commit.

+5
source share
1 answer

How to limit the log for all descendants of this version

As far as I know, there is no built-in Git command for this. However, you are almost there. Try

 git log --all --ancestry-path ^<rev> 

instead of this. This should limit the log to the descendants of <rev> ; note that, strictly speaking, <rev> is not in itself, so it does not get on the list.

For example, in my repo game (I played yours, look at the bottom of my answer),

 git log --all --ancestry-path ^D 

limits the log to commit E and

 git log --all --ancestry-path ^X 

restricts the log to a commit of Y

What happened to git log --all --ancestry-path D^! ?

TL DR

I understand that the team does not get all the children <rev> ; instead, he receives all the children of the parent (ref). I'm right?

Yes; your bottom latch is disabled by one.

More details

Since in your example, committ D and X are symmetric, just focus on commit D and deconstruct the command

 git log --all --ancestry-path D^! 

According to the corresponding Git man page ,

The suffix ^ followed by an exclamation mark is the same as giving commit <rev> , and then all of its parents with the ^ prefix to exclude them (and their ancestors).

Also, according to the git-log manual page ,

--all

Imagine that all refs in refs / are listed on the command line as <commit> .

Therefore in your case

 git log --all --ancestry-path D^! 

equivalently

 git log --ancestry-path D ^C feature master 

Also, since D reachable from master , the last command boils down to

 git log --ancestry-path ^C feature master 

This gives a log of all commits available from 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 latch is disabled by one . What do you really want to run

 git log --ancestry-path ^D feature master 

which coincides with

 git log --all --ancestry-path ^D 

Test

The following teams recreate the repo game:

 $ 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 

(Note that commits D and X can refer to their SHA or, more simply, to master~ and feature~ respectively.)

The command you proposed (I added the --oneline flag to reduce the result) does not really limit the log to the children of this 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 

but the one I suggest:

 # master~ == D $ git log --all --ancestry-path --oneline ^master~ b3d493a E # feature~ == X $ git log --all --ancestry-path --oneline ^feature~ e234427 Y 
+4
source

All Articles