user10082400
user10082400

Reputation:

How can we refer to a child of a commit?

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.

Upvotes: 2

Views: 650

Answers (2)

torek
torek

Reputation: 489293

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).

Upvotes: 0

chepner
chepner

Reputation: 531928

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.)

Upvotes: 1

Related Questions