Get commit hashes between 2 specified commit hash

145 Views Asked by At

What I am asking is somewhat similar to this question. However, it doesn't solve my problem. I want to list the commit hashes present between a start hash and an end hash (including the start and end). Let me give a simple example. For this repository, if we go to the commit history of the master branch, I want commits between f3b628f8f9c71a2cdfa052025c4a1ed78ee4c45d and d4bce13a443cf12da40a77c16c1e591f4f985b47. So I want the following commits to be printed -

f3b628f8f9c71a2cdfa052025c4a1ed78ee4c45d
c286db365e7374fe4d08f54077abb7fba81dd296
0bb0526b70870d57cbac9fcc8c4a7346a4ce5879
a5a7f852e45c7cadc8d1524bd4d14a1e39785aa5
9a5c33b16d07d62651ea80552e8782974c96bb8a
d4bce13a443cf12da40a77c16c1e591f4f985b47

I initially did something like this - git rev-list --reverse --remotes ^f3b628f8f9c71a2cdfa052025c4a1ed78ee4c45d^ HEAD -- but it gave me incorrect results.

After that I did this git rev-list --reverse --ancestry-path f3b628f8f9c71a2cdfa052025c4a1ed78ee4c45d..HEAD which gave me all but the first (starting) commit correctly.

So if someone can please help me on this, I will be really grateful. Also, if possible, please explain the command that you're using and how it's selecting those commits only. Thank you.

2

There are 2 best solutions below

1
jthill On BEST ANSWER

Git 2.38 added an optional argument to --ancestry-path, so now you can

git rev-list --ancestry-path=base base^! HEAD

which starts from base and HEAD and lists only commits with base in the path from those two tips but includes no ancestors of base.

$ git rev-list --reverse --ancestry-path=f3b6 f3b6^! d4bc
f3b628f8f9c71a2cdfa052025c4a1ed78ee4c45d
c286db365e7374fe4d08f54077abb7fba81dd296
0bb0526b70870d57cbac9fcc8c4a7346a4ce5879
a5a7f852e45c7cadc8d1524bd4d14a1e39785aa5
9a5c33b16d07d62651ea80552e8782974c96bb8a
d4bce13a443cf12da40a77c16c1e591f4f985b47
$ 

Even-harder-to-scrute (not actually inscrutable, just ... yeah, okay, this is wordplay, sue me) usages can get handy with that.

Before this addition, --ancestry-path base^! tip would include base but if it was a merge it would display reachable-from-tip children of base's parents that did not trace ancestry through base.

1
grg On
git rev-list --reverse --ancestry-path f3b628f^..

You almost had it with your last example, but the first hash is reachable from itself so excluded.

The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another.

https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection

To include f3b628f, choose the parent commit: f3b628f^.

If you place a ^ (caret) at the end of a reference, Git resolves it to mean the parent of that commit.

https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#_ancestry_references

Both the full hash and short hash work equally:

Git is smart enough to figure out what commit you’re referring to if you provide the first few characters of the SHA-1 hash

https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#_short_sha_1

and HEAD is implied:

You can also leave off one side of the syntax to have Git assume HEAD.

https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#_short_sha_1