Search code examples
gitgit-subtree

Rebase into a subtree


The situation is that we have two repositories, parent and child. The parent repo has the child repo as a subtree:

parent/
  child/

After some time, the child repository has diverged from its upstream (patches have been made for use of the parent project, which have not been contributed to child's upstream).

What is the right Git command to extract a patch from the child subtree (and only that specific patch) so it can be upstreamed?


Solution

  • To clarify, let's name the following branches:

    • main is the main branch of the parent repository (includes the patches that we don't want to upstream, but excludes the patches that we do want to upstream),
    • feature is the branch in which the patches that we want to upstream are; feature is based on main
    • child-main is the main branch of the child upstream (where we want to send our patches to)

    We want to create the child-feature branch, which contains all the modifications strictly in the feature branch without anything from main.

    We can do so like this:

    git switch -b child-feature feature
    git rebase -i -s subtree --onto child-main main
    

    Explanation:

    • git switch feature: switches to the feature branch
      • -b child-feature: creates the child-feature branch on top of the feature branch
    • git rebase: moves the current branch by copying all commits it contains
      • -i: interactive, not necessary but convenient to understand what is happening
      • -s subtree: use the subtree strategy, which knows how to deal with subtrees (all changes to the parent repository are removed, and all changes are 'moved' so the project root is the subtree directory)
      • --onto child-main: place the results on top of the child-main branch
      • main: only take into account changes that were made after the commit main points to (ignores previous patches)