If there are two git commits (or refs) A and B, and if A is known to be an ancestor of B in the history, is there an easy way to compute an expression that shows how A can be reached, starting from B (going backwards through the ancestry path)?
In other words, how to generate a description of A, as a relative path that starts out from B - with results like these:
A = B~1
- i.e. A is the direct parent of B (first parent, if B is a merge)
A = B^2
- i.e. A is the 2nd parent of (merge-commit) B
A = B~22^2~3
- i.e. A is the 3rd ("first") ancestor of the 2nd parent of a merge that is the 22nd ("first") ancestor of B
In practice, this might be useful as an indicator of how far two commits are apart in the history graph - sort of a condensed form of what --ancestry-path
can show in git log
(but also with fewer information).
Can something like this be generated using git built-in tooling...?
I realize that there can well be multiple valid paths, going from B back to A - so any resulting expression won't necessarily be unique.
The partly related question In Git, is there a way to get the "friendly" name for an arbitrary commit? linked by @Joe indeed led me to an easy way to allow for this - so thanks for the input :)
This can be answered using git name-rev
, although name-rev
really just works for named refs as reference to build a path for (so that wouldn't work directly with a SHA as reference).
Creating an intermediate, dummy ref makes it work though, so the following works
# Set sample values for A + B (B: current HEAD, A: root commit)
B=HEAD
A=`git rev-list HEAD | tail -n 1`
git branch tempRefToB ${B}
git name-rev --name-only --refs=tempRefToB ${A}
git branch -d tempRefToB
Sample output of the name-rev
command gives me what I was looking for (the temporary ref-name can easily be stripped back out from it, as needed):
tempRefToB~3334