git rebase --strategy with -Xours

-Xours tells Git to protect the new base. By bringing in only the additions that the incoming commits have made, it protects what is already in the new base.

Recap: A rebase moves a series of commits from one base to another base.

What does the --strategy do? When a rebase hits a conflict, git attempts to resolve it with one of these merge-strategies:

  • resolve
  • recursive (default)
    • ours
    • theirs
    • patience
    • ignore-space-change
    • ignore-all-space
    • ignore-space-at-eol
    • renormalize
    • no-renames
    • find-renames[=<n>]
    • subtree=<path>
  • octopus
  • ours
  • subtree

recursive with ours is one of our favorite strategies. To use it, choose --strategy recursive and pass the ours sub-option using the -X<sub-option> syntax.

// e.g. 1
git rebase --onto <the-new-base> <exclusive-start-ref> <inclusive-end-ref> --strategy recursive -Xours

// e.g. 2
git rebase --onto master topic-branch~5 topic-branch --strategy recursive -Xours

In the second example, Git takes the last four commits from topic-branch and plays them back onto master. If Git finds a conflicting hunk, it chooses the content of master; otherwise, Git adds the content of topic-branch. In other words, Git brings in to master only the additions that the topic branch has made.

We used -Xours recently to bring in deployment scripts from a long-lived experimental branch. We were only interested in the deployment scripts that experiemental-branch had added to the code base. If we had done a normal rebase, we would have had to deal with the conflicts that the experimental work had introduced to the existing code. Using -Xours instead told Git, "Just bring in the stuff that experimental-branch added." Those additions turned out to be the deployment scripts. Done. If there had been other additions, though, we could have easily detected and deleted them.

See also:

https://git-scm.com/docs/git-rebase#mergestrategies