{
    "mode": "man",
    "parameter": "git-merge-base",
    "section": "1",
    "url": "https://www.chedong.com/phpMan.php/man/git-merge-base/1/json",
    "generated": "2026-06-15T13:12:48Z",
    "synopsis": "git merge-base [-a|--all] <commit> <commit>...\ngit merge-base [-a|--all] --octopus <commit>...\ngit merge-base --is-ancestor <commit> <commit>\ngit merge-base --independent <commit>...\ngit merge-base --fork-point <ref> [<commit>]",
    "sections": {
        "NAME": {
            "content": "git-merge-base - Find as good common ancestors as possible for a merge\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "git merge-base [-a|--all] <commit> <commit>...\ngit merge-base [-a|--all] --octopus <commit>...\ngit merge-base --is-ancestor <commit> <commit>\ngit merge-base --independent <commit>...\ngit merge-base --fork-point <ref> [<commit>]\n\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "git merge-base finds best common ancestor(s) between two commits to use in a three-way merge.\nOne common ancestor is better than another common ancestor if the latter is an ancestor of\nthe former. A common ancestor that does not have any better common ancestor is a best common\nancestor, i.e. a merge base. Note that there can be more than one merge base for a pair of\ncommits.\n",
            "subsections": []
        },
        "OPERATION MODES": {
            "content": "As the most common special case, specifying only two commits on the command line means\ncomputing the merge base between the given two commits.\n\nMore generally, among the two commits to compute the merge base from, one is specified by the\nfirst commit argument on the command line; the other commit is a (possibly hypothetical)\ncommit that is a merge across all the remaining commits on the command line.\n\nAs a consequence, the merge base is not necessarily contained in each of the commit arguments\nif more than two commits are specified. This is different from git-show-branch(1) when used\nwith the --merge-base option.\n",
            "subsections": [
                {
                    "name": "--octopus",
                    "content": "Compute the best common ancestors of all supplied commits, in preparation for an n-way\nmerge. This mimics the behavior of git show-branch --merge-base.\n",
                    "long": "--octopus"
                },
                {
                    "name": "--independent",
                    "content": "Instead of printing merge bases, print a minimal subset of the supplied commits with the\nsame ancestors. In other words, among the commits given, list those which cannot be\nreached from any other. This mimics the behavior of git show-branch --independent.\n",
                    "long": "--independent"
                },
                {
                    "name": "--is-ancestor",
                    "content": "Check if the first <commit> is an ancestor of the second <commit>, and exit with status 0\nif true, or with status 1 if not. Errors are signaled by a non-zero status that is not 1.\n",
                    "long": "--is-ancestor"
                },
                {
                    "name": "--fork-point",
                    "content": "Find the point at which a branch (or any history that leads to <commit>) forked from\nanother branch (or any reference) <ref>. This does not just look for the common ancestor\nof the two commits, but also takes into account the reflog of <ref> to see if the history\nleading to <commit> forked from an earlier incarnation of the branch <ref> (see\ndiscussion on this mode below).\n",
                    "long": "--fork-point"
                }
            ]
        },
        "OPTIONS": {
            "content": "",
            "subsections": [
                {
                    "name": "-a, --all",
                    "content": "Output all merge bases for the commits, instead of just one.\n",
                    "flag": "-a",
                    "long": "--all"
                }
            ]
        },
        "DISCUSSION": {
            "content": "Given two commits A and B, git merge-base A B will output a commit which is reachable from\nboth A and B through the parent relationship.\n\nFor example, with this topology:\n\no---o---o---B\n/\n---o---1---o---o---o---A\n\nthe merge base between A and B is 1.\n\nGiven three commits A, B and C, git merge-base A B C will compute the merge base between A\nand a hypothetical commit M, which is a merge between B and C. For example, with this\ntopology:\n\no---o---o---o---C\n/\n/   o---o---o---B\n/   /\n---2---1---o---o---o---A\n\nthe result of git merge-base A B C is 1. This is because the equivalent topology with a merge\ncommit M between B and C is:\n\no---o---o---o---o\n/                 \\\n/   o---o---o---o---M\n/   /\n---2---1---o---o---o---A\n\nand the result of git merge-base A M is 1. Commit 2 is also a common ancestor between A and\nM, but 1 is a better common ancestor, because 2 is an ancestor of 1. Hence, 2 is not a merge\nbase.\n\nThe result of git merge-base --octopus A B C is 2, because 2 is the best common ancestor of\nall commits.\n\nWhen the history involves criss-cross merges, there can be more than one best common ancestor\nfor two commits. For example, with this topology:\n\n---1---o---A\n\\ /\nX\n/ \\\n---2---o---o---B\n\nboth 1 and 2 are merge-bases of A and B. Neither one is better than the other (both are best\nmerge bases). When the --all option is not given, it is unspecified which best one is output.\n\nA common idiom to check \"fast-forward-ness\" between two commits A and B is (or at least used\nto be) to compute the merge base between A and B, and check if it is the same as A, in which\ncase, A is an ancestor of B. You will see this idiom used often in older scripts.\n\nA=$(git rev-parse --verify A)\nif test \"$A\" = \"$(git merge-base A B)\"\nthen\n... A is an ancestor of B ...\nfi\n\nIn modern git, you can say this in a more direct way:\n\nif git merge-base --is-ancestor A B\nthen\n... A is an ancestor of B ...\nfi\n\ninstead.\n",
            "subsections": []
        },
        "DISCUSSION ON FORK-POINT MODE": {
            "content": "After working on the topic branch created with git switch -c topic origin/master, the history\nof remote-tracking branch origin/master may have been rewound and rebuilt, leading to a\nhistory of this shape:\n\no---B2\n/\n---o---o---B1--o---o---o---B (origin/master)\n\\\nB0\n\\\nD0---D1---D (topic)\n\nwhere origin/master used to point at commits B0, B1, B2 and now it points at B, and your\ntopic branch was started on top of it back when origin/master was at B0, and you built three\ncommits, D0, D1, and D, on top of it. Imagine that you now want to rebase the work you did on\nthe topic on top of the updated origin/master.\n\nIn such a case, git merge-base origin/master topic would return the parent of B0 in the above\npicture, but B0^..D is not the range of commits you would want to replay on top of B (it\nincludes B0, which is not what you wrote; it is a commit the other side discarded when it\nmoved its tip from B0 to B1).\n\ngit merge-base --fork-point origin/master topic is designed to help in such a case. It takes\nnot only B but also B0, B1, and B2 (i.e. old tips of the remote-tracking branches your\nrepository’s reflog knows about) into account to see on which commit your topic branch was\nbuilt and finds B0, allowing you to replay only the commits on your topic, excluding the\ncommits the other side later discarded.\n\nHence\n\n$ forkpoint=$(git merge-base --fork-point origin/master topic)\n\nwill find B0, and\n\n$ git rebase --onto origin/master $forkpoint topic\n\nwill replay D0, D1 and D on top of B to create a new history of this shape:\n\no---B2\n/\n---o---o---B1--o---o---o---B (origin/master)\n\\                   \\\nB0                  D0'--D1'--D' (topic - updated)\n\\\nD0---D1---D (topic - old)\n\nA caveat is that older reflog entries in your repository may be expired by git gc. If B0 no\nlonger appears in the reflog of the remote-tracking branch origin/master, the --fork-point\nmode obviously cannot find it and fails, avoiding to give a random and useless result (such\nas the parent of B0, like the same command without the --fork-point option gives).\n\nAlso, the remote-tracking branch you use the --fork-point mode with must be the one your\ntopic forked from its tip. If you forked from an older commit than the tip, this mode would\nnot find the fork point (imagine in the above sample history B0 did not exist, origin/master\nstarted at B1, moved to B2 and then B, and you forked your topic at origin/master^ when\norigin/master was B1; the shape of the history would be the same as above, without B0, and\nthe parent of B1 is what git merge-base origin/master topic correctly finds, but the\n--fork-point mode will not, because it is not one of the commits that used to be at the tip\nof origin/master).\n",
            "subsections": []
        },
        "SEE ALSO": {
            "content": "git-rev-list(1), git-show-branch(1), git-merge(1)\n",
            "subsections": []
        },
        "GIT": {
            "content": "Part of the git(1) suite\n\n\n\nGit 2.34.1                                   02/26/2026                            GIT-MERGE-BASE(1)",
            "subsections": []
        }
    },
    "summary": "git-merge-base - Find as good common ancestors as possible for a merge",
    "flags": [
        {
            "flag": "-a",
            "long": "--all",
            "arg": null,
            "description": "Output all merge bases for the commits, instead of just one."
        }
    ],
    "examples": [],
    "see_also": [
        {
            "name": "git-rev-list",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/git-rev-list/1/json"
        },
        {
            "name": "git-show-branch",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/git-show-branch/1/json"
        },
        {
            "name": "git-merge",
            "section": "1",
            "url": "https://www.chedong.com/phpMan.php/man/git-merge/1/json"
        }
    ],
    "tldr": {
        "source": "official",
        "description": "Find a common ancestor of two commits.",
        "examples": [
            {
                "description": "Print the best common ancestor of two commits",
                "command": "git merge-base {{commit_1}} {{commit_2}}"
            },
            {
                "description": "Print all best common ancestors of two commits",
                "command": "git merge-base {{-a|--all}} {{commit_1}} {{commit_2}}"
            },
            {
                "description": "Check if a commit is an ancestor of a specific commit",
                "command": "git merge-base --is-ancestor {{ancestor_commit}} {{commit}}"
            }
        ]
    }
}