Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import existing Git repository into another?

I have a Git repository in a folder called XXX, and I have second Git repository called YYY.

I want to import the XXX repository into the YYY repository as a subdirectory named ZZZ and add all XXX's change history to YYY.

Folder structure before:

├── XXX │   ├── .git │   └── (project files) └── YYY     ├── .git     └── (project files) 

Folder structure after:

YYY ├── .git  <-- This now contains the change history from XXX ├──  ZZZ  <-- This was originally XXX │    └── (project files) └──  (project files) 

Can this be done, or must I resort to using sub-modules?

like image 652
Vijay Patel Avatar asked Nov 05 '09 20:11

Vijay Patel


People also ask

How do I import a Git repository to another repository?

Under "Your old repository's clone URL", type the URL of the project you want to import. Choose your personal account or an organization to own the repository, then type a name for the repository on GitHub. Specify whether the new repository should be public or private.


2 Answers

Probably the simplest way would be to pull the XXX stuff into a branch in YYY and then merge it into master:

In YYY:

git remote add other /path/to/XXX git fetch other git checkout -b ZZZ other/master mkdir ZZZ git mv stuff ZZZ/stuff                      # repeat as necessary for each file/dir git commit -m "Moved stuff to ZZZ" git checkout master                 git merge ZZZ --allow-unrelated-histories   # should add ZZZ/ to master git commit git remote rm other git branch -d ZZZ                           # to get rid of the extra branch before pushing git push                                    # if you have a remote, that is 

I actually just tried this with a couple of my repos and it works. Unlike Jörg's answer it won't let you continue to use the other repo, but I don't think you specified that anyway.

Note: Since this was originally written in 2009, git has added the subtree merge mentioned in the answer below. I would probably use that method today, although of course this method does still work.

like image 59
ebneter Avatar answered Oct 03 '22 22:10

ebneter


If you want to retain the exact commit history of the second repository and therefore also retain the ability to easily merge upstream changes in the future then here is the method you want. It results in unmodified history of the subtree being imported into your repo plus one merge commit to move the merged repository to the subdirectory.

git remote add XXX_remote <path-or-url-to-XXX-repo> git fetch XXX_remote git merge -s ours --no-commit --allow-unrelated-histories XXX_remote/master git read-tree --prefix=ZZZ/ -u XXX_remote/master git commit -m "Imported XXX as a subtree." 

You can track upstream changes like so:

git pull -s subtree XXX_remote master 

Git figures out on its own where the roots are before doing the merge, so you don't need to specify the prefix on subsequent merges.

The downside is that in the merged history the files are unprefixed (not in a subdirectory). As a result git log ZZZ/a will show you all the changes (if any) except those in the merged history. You can do:

git log --follow -- a 

but that won't show the changes other then in the merged history.

In other words, if you don't change ZZZ's files in repository XXX, then you need to specify --follow and an unprefixed path. If you change them in both repositories, then you have 2 commands, none of which shows all the changes.

Git versions before 2.9: You don’t need to pass the --allow-unrelated-histories option to git merge.

The method in the other answer that uses read-tree and skips the merge -s ours step is effectively no different than copying the files with cp and committing the result.

Original source was from github's "Subtree Merge" help article. And another useful link.

like image 38
ColinM Avatar answered Oct 03 '22 23:10

ColinM