Before I give you an answer, consider this commit graph:
o -----------
/
... - A - o - o - o - B
/
o ----- o
Each o
represents a commit, as do A
and B
(they're just letters to let us talk about specific commits). How many commits are there between commits A
and B
?
That said, in more linear cases, just use git rev-list --count A..B
and then decide what you mean by "between" (does it include B and exclude A? that's how git rev-list --count
will behave). In branchy cases like this, you'll get all the commits down all the branches; add --first-parent
, for instance, to follow just the "main line".
(You also mentioned "commitish", suggesting that we might have annotated tags. That won't affect the output from git rev-list
, which only counts specific commits.)
Edit: Since git rev-list --count A..B
includes commit B
(while omitting commit A
), and you want to exclude both end-points, you need to subtract one. In modern shells you can do this with shell arithmetic:
count=$(($(git rev-list --count A..B) - 1))
For instance:
$ x=$(($(git rev-list --count HEAD~3..HEAD) - 1))
$ echo $x
2
(this particular repo has a very linear graph structure, so there are no branches here and there are two commits "between" the tip and three-behind-the-tip). Note, however, that this will produce -1 if A
and B
identify the same commit:
$ x=$(($(git rev-list --count HEAD..HEAD) - 1))
$ echo $x
-1
so you might want to check that first:
count=$(git rev-list --count $start..$end)
if [ $count -eq 0 ]; then
... possible error: start and end are the same commit ...
else
count=$((count - 1))
fi
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…