2

Most commits have 1 parent commit. However, some commits have multiple parents. For instance, merge commits that were created under the --no-ff (no fast-forward) flag have at least 2 parents.

Is there a command in git that shows the exact number of parents a specific commit has?

Pedro Delfino
  • 1,813
  • 1
  • 12
  • 20
  • 1
    I think 1 or 2 are really the only common number of parents. While I think in theory any number is possible, I don't know of any workflows that creates >2 parents. Edit: [there are samples of it in the wild](https://softwareengineering.stackexchange.com/questions/314215/can-a-git-commit-have-more-than-2-parents). – Joachim Sauer Jul 16 '21 at 17:16

2 Answers2

6

To view the list of parent commits:

git show -s --format=%p [commit-id]

To just show the number of parents:

git show -s --format=%p [commit-id] | wc -w

Explanation:

TTT
  • 14,202
  • 7
  • 53
  • 56
2

For a casual or human-readable answer, use git show as in TTT's post.

However, despite the clean use of --format, the output of git show is allowed to change: it is a "porcelain command" in git's "plumbing/porcelain separation". (The same is true of git log --format.) Changes might be unlikely, but you might also see errors and other human-directed output as git show is intended for human consumption rather than script consumption.

For a more rigorous or spec-guaranteed list of parents, suitable for long-lived shell scripts or tool integration, you'll want to use a plumbing command like git cat-file, similar to extracting a commit date without git log.

git cat-file -p [commit-id] | sed -ne '/^$/q;/^parent/p' | wc -l
  • git cat-file -p will pretty-print the object with the given ID. Revisions like HEAD also work here.
  • sed here will both filter and truncate the output:
    • -n suppresses all output.
    • -e uses a script specified on the command line.
    • /^$/q tells sed to quit if it sees a blank line, like the one separating commit metadata from its message. This prevents misinterpreting the word "parent" in your commit body text.
    • ; separates sed commands.
    • /^parent/p tells sed to print only the lines that start with parent, overriding -n.
  • wc -l prints the number of resulting lines.

Once again, for most cases git show is a more idiomatic way of doing this, since it reads and parses the commit all in one command and has already been written with edge-cases and oddities in mind. However, for developers of long-lived git tools, plumbing commands might be a more guaranteed solution.

Jeff Bowman
  • 83,326
  • 15
  • 202
  • 231
  • 1
    Consider also `git rev-list --no-walk --parents | wc -w` (though you then have to subtract 1 or otherwise fuss about with the output). – torek Jul 18 '21 at 05:02