git checkout: detailed meaning of “theirs” and “ours”

The git checkout documentation says:

When checking out paths from the index, check out stage #2 (ours) or #3 (theirs) for unmerged paths.

  • commit count calculation in git-describe
  • What are .rej files which are created during merge
  • Git “leaky” branches?
  • Migrate SVN to git with cleanup
  • Merge/Branch Strategy
  • How should I manage Test Harnesses in Git - Should they be in a separate repo?
  • What’s the meaning of “stage #2” and “stage #3” during merge, rebase and cherry-pick? Is there a way to query theses “stages” before running the command to make sure it will retrieve the correct version?

  • Visual Studio - AppBuilder - Git Hub - .sou file issue
  • Cannot use remote repository in a composer on windows
  • Why does git keep messing with my line endings?
  • Git diff thinks line endings are LF when EOL is set to CRLF in .gitattributes
  • Auto-push changes to one folder in a git repository to github?
  • Maintain different directory structure in different git branches
  • 2 Solutions collect form web for “git checkout: detailed meaning of “theirs” and “ours””

    These are documented (though not all that clearly, I think) in the gitrevisions documentation:

    A colon, optionally followed by a stage number (0 to 3) and a colon, followed by a path, names a blob object in the index at the given path. A missing stage number (and the colon that follows it) names a stage 0 entry. During a merge, stage 1 is the common ancestor, stage 2 is the target branch’s version (typically the current branch), and stage 3 is the version from the branch which is being merged.

    To these, you then need to add knowledge about how git rebase and git cherry-pick work.

    Normal cherry picking is well-defined: “ours” is the HEAD version, i.e., the branch you were (and still are) on, while “theirs” is the commit you’re actively picking. When you cherry-pick a single commit, it’s all pretty obvious: stage #1 is the common ancestor, stage #2 is the version from the tip of your current branch, and stage #3 is the version you’re cherry-picking.

    If you cherry-pick a series of commits, this is still true, it’s just true iteratively. Say you’re cherry-picking three commits, for instance. Git simply does the three one-at-a-time. During the first cherry-pick, stage #2 is the tip of your branch, and stage #3 is the version from the first commit being cherry-picked. Once that commit cherry-pick finishes, git makes a new commit, advancing the tip of your branch. Then, during the second cherry-pick, stage #2 is the tip of your branch, which is the commit your first cherry-pick made, and stage #3 is the version from the second commit being picked. This repeats again for the final commit. Each time, stage #3 is “their” version.

    Rebase, however, is a little tricky. Internally, it starts by getting you onto a new, anonymous branch (a “detached HEAD”). Then it runs git cherry-pick to pick each commit from your original branch. This means that “ours” is the detached HEAD version, while “theirs” is the version from your original branch. Just like cherry-pick, this repeats iteratively for every commit to be picked (literally so in the case of an interactive rebase, where you edit the pick lines). Once the rebase finishes, git simply shuffles the branch label around, so that the new anonymous branch that you just made is your code.

    In short, you can think of rebase as “reversing the ours/theirs settings”—but this is an exaggeration. It might be more accurate to say that stage 2 is your new, melded-in code, and stage 3 is your old code.

    The Git documentation for merge (as well as a few other places) explains that an index file records up to three versions, or stages:

    For conflicting paths, the index file records up to three versions: stage 1 stores the version from the common ancestor, stage 2 from HEAD, and stage 3 from MERGE_HEAD (you can inspect the stages with git ls-files -u). The working tree files contain the result of the “merge” program; i.e. 3-way merge results with familiar conflict markers <<< === >>>.

    Here is a diagram showing what the three stages are in a typical Git merge:

    Common Ancestor -> C1  --- C2         <- MERGE_HEAD (Stage 3)
    (Stage 1)             \
                            --- C3 --- C4 <- HEAD (Stage 2)

    This assumes that the branch whose HEAD is C4 is being merged back onto the branch ending in C2.

    As the documentation states, you can actually view the stages by typing:

    git ls-files -u
    Git Baby is a git and github fan, let's start git clone.