Given a branch name or a tag name
, we can refer to its parent by name~1
. Can we refer to one of its children in some way?
Thanks.
As chepner said, the information is not directly available, as Git only stores backwards links. A parent commit always exists when its child is created, but its children do not exist when the parent is created. Once a commit has been created, nothing about it can ever be changed, so there's no way to hook it up to its children.
Nonetheless, if you have a direction in mind, you can find the children of some commit in that direction. Here's what I mean: suppose the graph looks like this:
B--D--E <-- branch1
/
...--o--A
\
C--F--G <-- branch2
And, suppose you have the name or hash ID of commit A
in your paws at the moment. You can find the hash ID of commit B
by searching from A
in the "branch1" direction, and the hash ID of commit C
by searching from A
in the "branch2" direction. To do this, use:
git rev-list --reverse --topo-order --ancestry-path A..branch1
which will list out the hash IDs for commits B
, D
, and E
in that order. Replace branch1
with branch2
to get C
, F
, and G
in that order.
Be aware that if the graph looks like this:
B--E <-- branch1
/ /
...--o--A--D
\
C <-- branch2
you could get either B
or D
first, in the A..branch1
direction. To check for such situations, instead of (or in addition to) using --topo-order
and/or --reverse
, collect all the commits along this ancestry path, and for each such commit, check all that commit's parents:
ahash=$(git rev-parse A^{commit}) # in case A is a branch or tag name, for instance
for hash in $(git rev-list --ancestry-path $ahash..branch1); do
if git rev-parse $hash^@ | grep -q $ahash; then
echo $hash is a child of $ahash
fi
done
(this code is untested).
A Git repository is represented as a DAG (directed, acyclic graph) of commits. Each commit includes one pointer to each of its parents, but no information about what commits have it as a parent. That's why you can only refer to the parents of a commit (name~1
, name~2
, etc), not the commits that have name
as a parent.
(Most commits have a single parent, but a merge commit is an example of a commit with 2 or more parents, depending on how many branches were involved in the merge.)