Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

merging git repositories at different directory levels

Tags:

git

I have a repository B whose contents need to reside in the subdirectory of A ... in A/src/B. I want to end up with one repository A that includes history of commits from both A and B.

Other solutions on the web seem to show me how to keep the trees intact in separate sub-trees or merge selected parts of repositories having the same directory structure.

So, is there a way to do this?

like image 583
fodon Avatar asked Jan 19 '12 15:01

fodon


People also ask

Can we merge two different repositories?

To combine two separate Git repositories into one, add the repository to merge in as a remote to the repository to merge into. Then, combine their histories by merging while using the --allow-unrelated-histories command line option.

Can we merge different branches from different repositories in a single branch?

Adaptions. If you already have a local copy of a repository containing the code, you could also use that for the merging process. You just need to make sure you do not mix up local development and merging and maybe you need to handle more remote repositories as you have some more for your development.

Does merging change both branches?

No, merging does only affect one branch.


1 Answers

This is pretty simple, in fact, but the commands aren't necessarily obvious. A nice alternative if you're going to need to incorporate more updates from B later is git-subtree (not to be confused with the subtree merge strategy). You say that you want to end up with one repository, so using git submodules isn't appropriate.

Here's the classic way of doing this, with some explanation:

  1. Change into repository A:

    cd A
    
  2. Fetch the master branch (or whatever) from repository B, and (temporarily) store it as FETCH_HEAD:

    git fetch /home/whoever/dev/B master
    
  3. Do a merge that ignores the changes from FETCH_HEAD, but don't commit. This is so that we can later commit the merge and the parents of the merge will include FETCH_HEAD. (That parent is stored in .git/MERGE_HEAD.)

    git merge -s ours --no-commit FETCH_HEAD
    
  4. Read the tree from the FETCH_HEAD (still the fetched master branch of B) into the staging area at the subdirectory src/B. The -u means to reflect the result of that in the working copy as well:

    git read-tree --prefix=src/B/ -u FETCH_HEAD
    
  5. Finally commit the result:

    git commit -m "Merge in the history of master from B into src/B"
    

This is similar to what is suggested in GitHub's help page on the subtree merge strategy, except that I've skipped creating a remote for B. Note that also this procedure hasn't actually used the subtree merge strategy - that would only be for incoporating further changes from B, if I understand it correctly.

like image 120
Mark Longair Avatar answered Nov 06 '22 04:11

Mark Longair