Programming
git merge repository git-subtree
Updated Fri, 27 May 2022 14:33:06 GMT

How do you merge two Git repositories?


Consider the following scenario:

I have developed a small experimental project A in its own Git repo. It has now matured, and I'd like A to be part of larger project B, which has its own big repository. I'd now like to add A as a subdirectory of B.

How do I merge A into B, without losing history on any side?




Solution

A single branch of another repository can be easily placed under a subdirectory retaining its history. For example:

git subtree add --prefix=rails git://github.com/rails/rails.git master

This will appear as a single commit where all files of Rails master branch are added into "rails" directory. However the commit's title contains a reference to the old history tree:

Add 'rails/' from commit <rev>

Where <rev> is a SHA-1 commit hash. You can still see the history, blame some changes.

git log <rev>
git blame <rev> -- README.md

Note that you can't see the directory prefix from here since this is an actual old branch left intact. You should treat this like a usual file move commit: you will need an extra jump when reaching it.

# finishes with all files added at once commit
git log rails/README.md
# then continue from original tree
git log <rev> -- README.md

There are more complex solutions like doing this manually or rewriting the history as described in other answers.

The git-subtree command is a part of official git-contrib, some packet managers install it by default (OS X Homebrew). But you might have to install it by yourself in addition to git.





Comments (5)

  • +2 – Here are instructions on how to install Git SubTree (as of June 2013): stackoverflow.com/a/11613541/694469 (and I replaced git co v1.7.11.3 with ... v1.8.3). — Jun 07, 2013 at 14:31  
  • +1 – Thanks for the heads up about the below answer. As of git 1.8.4 'subtree' still isn't included (at least not on the Ubuntu 12.04 git ppa (ppa:git-core/ppa) ) — Sep 30, 2013 at 02:10  
  • +1 – I can confirm that after this, git log rails/somefile will not display that file's commits history except the merge commit. As @artfulrobot suggested, check Greg Hewgill's answer. And you might need to use git filter-branch on the repo you want to include. — Oct 08, 2013 at 12:07  
  • +8 – Or read Eric Lee's "Merging Two Git Repositories Into One Repository Without Losing File History" saintgimp.org/2013/01/22/… — Oct 08, 2013 at 12:17  
  • +6 – As others have said, git subtree may not do what you think! See here for a more complete solution. — Feb 01, 2014 at 08:13