LinuxCommandLibrary

git-merge-base

Find the best common ancestor for merging

TLDR

Print the best common ancestor of two commits

$ git merge-base [commit_1] [commit_2]
copy

Print all best common ancestors of two commits
$ git merge-base [[-a|--all]] [commit_1] [commit_2]
copy

Check if a commit is an ancestor of a specific commit
$ git merge-base --is-ancestor [ancestor_commit] [commit]
copy

SYNOPSIS

git merge-base [--all] commit commit...
git merge-base --octopus commit...
git merge-base --independent commit...
git merge-base --is-ancestor commit commit
git merge-base --fork-point rev [rev]

PARAMETERS

--all
    Output all common ancestors, not just the best one. This can result in multiple lines of output.

--octopus
    Find a common merge base for an N-way merge (octopus merge). This finds the common ancestor of all specified commits and reports the best ones that are not ancestors of each other.

--independent
    Identify independent commit chains that are not ancestors of each other. These are typically the tips of merge bases found by --octopus mode when multiple independent merge bases exist.

--is-ancestor
    Check if the first commit is an ancestor of the second commit. Exits with 0 status code if true, 1 otherwise. No output is produced.

--fork-point
    Find a common ancestor using the reflog to approximate where a branch diverged from another. This is useful for rebasing a series of private commits that were originally based on an upstream branch, even if the upstream branch has been rebased itself.

DESCRIPTION

The git merge-base command helps in finding a good common ancestor between two or more commits. It's primarily used internally by git merge and git rebase to determine the common point from which changes diverged. For a standard two-branch merge (git merge A B), git merge-base A B typically finds the single common ancestor. This ancestor is crucial for performing a 3-way merge, where changes from both branches are applied relative to this common base.

When there are multiple common ancestors, git merge-base intelligently selects the "best" common ancestor, usually the one that is an ancestor of all other common ancestors. This ensures that the merge is based on the most recent shared history. The command also supports modes for finding common ancestors for N-way merges (--octopus), identifying independent heads (--independent), and checking ancestry relationships (--is-ancestor). Understanding git merge-base is key to grasping how Git handles branching and merging operations internally.

CAVEATS

In scenarios with complex histories like "criss-cross merges" (where two branches merge and then one of the merged branches merges back into the other, creating diamond shapes in the history), there might be multiple "best" common ancestors. git merge-base attempts to find the most appropriate one but its choice might not always be what a human intuitively expects in highly convoluted graphs. When given more than two commits without --octopus or --independent, it finds a common ancestor of all of them, which can also lead to less intuitive results in specific graph configurations compared to a simple two-commit merge base.

BEST COMMON ANCESTOR

When multiple common ancestors exist between two commits, git merge-base selects the 'best' one. This 'best' ancestor is defined as the unique common ancestor that is an ancestor of all other common ancestors. This ensures that the merge base is the most recent shared point in the history that precedes both branches, minimizing the set of changes that need to be merged.

USAGE WITH MULTIPLE COMMITS

When git merge-base is given more than two commits without the --octopus or --independent options, it finds a common ancestor of all of them. This is internally handled by computing the merge base of the first two commits, then finding the merge base of that result with the third commit, and so on. This process aims to identify a single point in history that precedes all specified branches.

HISTORY

The git merge-base command is a fundamental "plumbing" utility within Git's architecture, designed to find common ancestors. It has been a core component since the early days of Git, forming the basis for higher-level commands like git merge and git rebase. Its various modes (--octopus, --independent, --is-ancestor) have been added over time to address increasingly complex merging scenarios and to provide more granular control over ancestry queries.

SEE ALSO

Copied to clipboard