5

It appears that the ^ and ~ syntax in git only ever goes to the left parent commit (the commit into which the right parent is merged). In my specific case, I have a tree like this:

$ git log --pretty=format:"%h" --graph
*   f5712e3
|\  
| * d0f8257
* | e1fe071
|/  
* e0fff07

I'm finding both git log HEAD^ -1 and git log HEAD~1 -1 give me the left parent e1fe071. What is the conventional syntax to get the right parent?

Steven
  • 17,796
  • 13
  • 66
  • 118

1 Answers1

9
$ git log HEAD^2

The caret allows you to choose among a commit’s immediate parents, as described in the git rev-parse documentation.

<rev>^, e.g., HEAD^, v1.5.1^0

A suffix ^ to a revision parameter means the first parent of that commit object. ^<n> means the n-th parent (i.e., <rev>^ is equivalent to <rev>^1). As a special rule, <rev>^0 means the commit itself and is used when <rev> is the object name of a tag object that refers to a commit object.

To determine which is which, the output* of git show lists the parents in order. For example, head of the master branch in libgit2 is a merge commit, a3ef70b.

$ git show master
commit a3ef70bb405a05c16fb533d828da2510ff751224
Merge: c4c47fc 8aba3d4
Author: Edward Thomson <ethomson@edwardthomson.com>
Date:   Tue Dec 30 11:53:55 2014 -0600

    Merge pull request #2761 from libgit2/cmn/fetch-prune

    Remote-tracking branch prunning

Notice the second line of output, beginning Merge:, that lists the parents in order. We can verify this property using git rev-parse as in

$ git rev-parse master^1
c4c47fc2861935d8e373319c0734ea7b2ce34a73

and

$ git rev-parse master^2
8aba3d47cf96e24e02601175f900f0e851077c1a

Inspecting the source confirms.

strbuf_addstr(sb, "Merge:");

while (parent) {
    struct commit *p = parent->item;
    const char *hex = NULL;
    if (pp->abbrev)
        hex = find_unique_abbrev(p->object.sha1, pp->abbrev);
    if (!hex)
        hex = sha1_to_hex(p->object.sha1);
    parent = parent->next;

    strbuf_addf(sb, " %s", hex);
}

Related answer: Get parents of a merge commit in git


* The documentation for git show gives a caveat regarding pedigree of commits:

If the commit is a merge, and if the pretty-format is not oneline, email or raw, an additional line is inserted before the Author: line. This line begins with "Merge: " and the sha1s of ancestral commits are printed, separated by spaces. Note that the listed commits may not necessarily be the list of the direct parent commits if you have limited your view of history: for example, if you are only interested in changes related to a certain directory or file.

Community
  • 1
  • 1
Greg Bacon
  • 134,834
  • 32
  • 188
  • 245
  • How do you know which is which? Depending on whatever factors, a desired parent may be either on the left or on the right. – Amedee Van Gasse Dec 30 '14 at 12:55
  • I understand your answer, although it does not address my particular issue. However since this situation occurs only once in my repository, I think I'll just resort to manual inspection. – Amedee Van Gasse Jan 01 '15 at 19:08