How do you merge two Git repositories?

后端 未结 23 3249
耶瑟儿~
耶瑟儿~ 2020-11-21 05:45

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 projec

相关标签:
23条回答
  • 2020-11-21 06:01

    When you want to merge three or more projects in a single commit, do the steps as described in the other answers (remote add -f, merge). Then, (soft) reset the index to old head (where no merge happened). Add all files (git add -A) and commit them (message "Merging projects A, B, C, and D into one project). This is now the commit-id of master.

    Now, create .git/info/grafts with following content:

    <commit-id of master> <list of commit ids of all parents>
    

    Run git filter-branch -- head^..head head^2..head head^3..head. If you have more than three branches, just add as much head^n..head as you have branches. To update tags, append --tag-name-filter cat. Do not always add that, because this might cause a rewrite of some commits. For details see man page of filter-branch, search for "grafts".

    Now, your last commit has the right parents associated.

    0 讨论(0)
  • 2020-11-21 06:02

    If you're trying to simply glue two repositories together, submodules and subtree merges are the wrong tool to use because they don't preserve all of the file history (as people have noted on other answers). See this answer here for the simple and correct way to do this.

    0 讨论(0)
  • 2020-11-21 06:03

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

    cd path/to/project-b
    git remote add project-a /path/to/project-a
    git fetch project-a --tags
    git merge --allow-unrelated-histories project-a/master # or whichever branch you want to merge
    git 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-a
    git 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.

    0 讨论(0)
  • 2020-11-21 06:05

    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/B
    git merge -s ours --allow-unrelated-histories --no-commit Bproject/master
    git read-tree --prefix=dir-B/ -u Bproject/master
    git 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.

    0 讨论(0)
  • 2020-11-21 06:05

    Merging 2 repos

    git clone ssh://<project-repo> project1
    cd project1
    git remote add -f project2 project2
    git merge --allow-unrelated-histories project2/master
    git remote rm project2
    
    delete the ref to avoid errors
    git update-ref -d refs/remotes/project2/master
    
    0 讨论(0)
  • 2020-11-21 06:07

    I kept losing history when using merge, so I ended up using rebase since in my case the two repositories are different enough not to end up merging at every commit:

    git clone git@gitorious/projA.git projA
    git clone git@gitorious/projB.git projB
    
    cd projB
    git remote add projA ../projA/
    git fetch projA 
    git rebase projA/master HEAD
    

    => resolve conflicts, then continue, as many times as needed...

    git rebase --continue
    

    Doing this leads to one project having all commits from projA followed by commits from projB

    0 讨论(0)
提交回复
热议问题