问题
With Git you can list all ancestors of b, excluding all ancestors of a:
git log a..b
You can also list all first-parent ancestors of b, excluding all ancestors of a:
git log --first-parent a..b
But I want to list all first-parent ancestors of b, excluding all first-parent ancestors of a. I haven't found any way to get the first-parent requirement to also apply to the negative part(s) of a revision range.
Is there a way to do this? If there's no way to do this using only Git commands, is there a plausible way to achieve this with a Bash script?
Some more detail. For this commit graph (parents shown in left-to-right order):
b --> 9
|\
| \
| \
a --> 6 7 8
|\ | |
| \ | |
| \| |
3 4 5
\ | /
\ | /
\|/
2
|
|
1
git log a..b would list 9, 8, 7 and 5. git log --first-parent a..b would list 9 and 7. I'm looking for a way to list 9, 7 and 4.
回答1:
You can build the two lists, and use grep to exclude one from another :
git rev-list --first-parent a > lista.txt
git rev-list --first-parent b > listb.txt
# use grep, use '-f' to read patterns from 'lista.txt',
# use '-v' to say "exclude these patterns"
cat listb.txt | grep -v -f lista.txt
You can avoid creating the files on disk ; in bash and zsh you can use a so called process substitution (syntax is : <(command)) :
git rev-list --first-parent b | grep -v -f <(git rev-list --first-parent a)
One extra flag you can use with grep is -F, --fixed-strings) : since in this case all patterns are flat strings (not regexps), you can indicate that to grep, it speeds things up
git rev-list --first-parent b | grep -v -F -f <(git rev-list --first-parent a)
来源:https://stackoverflow.com/questions/62943962/list-git-commits-between-a-and-b-considering-only-first-parents-of-b-and-only-f