How do you merge two Git repositories? How do you merge two Git repositories? git git

How do you merge two Git repositories?


If you want to merge project-a into project-b:

cd path/to/project-bgit remote add project-a /path/to/project-agit fetch project-a --tagsgit merge --allow-unrelated-histories project-a/master # or whichever branch you want to mergegit remote remove project-a

Taken from: git merge different repositories?

This method worked pretty well for me, it's shorter and in my opinion a lot cleaner.

In case you want to put project-a into a subdirectory, you can use git-filter-repo (filter-branch is discouraged). Run the following commands before the commands above:

cd path/to/project-agit filter-repo --to-subdirectory-filter project-a

An example of merging 2 big repositories, putting one of them into a subdirectory: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731

Note: The --allow-unrelated-histories parameter only exists since git >= 2.9. See Git - git merge Documentation / --allow-unrelated-histories

Update: Added --tags as suggested by @jstadler in order to keep tags.


Here are two possible solutions:

Submodules

Either copy repository A into a separate directory in larger project B, or (perhaps better) clone repository A into a subdirectory in project B. Then use git submodule to make this repository a submodule of a repository B.

This is a good solution for loosely-coupled repositories, where development in repository A continues, and the major portion of development is a separate stand-alone development in A. See also SubmoduleSupport and GitSubmoduleTutorial pages on Git Wiki.

Subtree merge

You can merge repository A into a subdirectory of a project B using the subtree merge strategy. This is described in Subtree Merging and You by Markus Prinz.

git remote add -f Bproject /path/to/Bgit merge -s ours --allow-unrelated-histories --no-commit Bproject/mastergit read-tree --prefix=dir-B/ -u Bproject/mastergit commit -m "Merge B project as our subdirectory"git pull -s subtree Bproject master

(Option --allow-unrelated-histories is needed for Git >= 2.9.0.)

Or you can use git subtree tool (repository on GitHub) by apenwarr (Avery Pennarun), announced for example in his blog post A new alternative to Git submodules: git subtree.


I think in your case (A is to be part of larger project B) the correct solution would be to use subtree merge.


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 commitgit log rails/README.md# then continue from original treegit 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.