Search code examples
gitgit-branchgit-mergegit-subtree

Merge changes from one repo to another with different tree structures


I have two Git repos, foo/master and bar/master:

In foo:

code_root
->dirA
  ->dirB
    -> *some files*

In bar:

code_root
  -> *same files as above*

Now someone has made changes to *some files*... how do I get those changes merged into *same files as above*?

When I say "merged" I mean I need the history (commit messages, log hashes etc.) of the deltas to come over as well.


Solution

  • You can split the changes out to the subtree level, and then merge with your other branch:

    # from your foo project
    git subtree split --prefix=dirA/dirB/ --branch=temp-branch [--onto=<onto-sub-note1>] [<commit-sub-note2>]
    

    onto sub-note 1: It seems like since bar project exists at all, you must have copied it at some point in time, and started this as the new library, in which case, if you want all changes made after that, you'd specify this bar commit id when the changes were brought in.

    commit sub-note 2: You'd then want to specify the commit id that was used when you copied the sub-project in the first place, so that you only get the changes since then to merge into the copy of bar you already have (this will maintain the history of what you missed). Use syntax like this to include the commit id itself up to the latest: 0abc210^..

    You can also use --rejoin to make a commit back into your foo project, which will make it easier to push changes later if you would like to continue development on bar from withing your foo project. The commit back into foo is kind of pointless other than to help the subtree command base it's split changes more easily in the future.

    After running the split command, you'll be in a branch of foo, which only has those files. From there you can do a normal merge with your bar project or start a new project and merge bar into that (since it probably doesn't have a proper history). You may want to rebase to the diverge point or something before trying to do that merge though.

    Edit: Also here's the reference for git subtree commands