Search code examples
gitgit-merge

Combine two repositories with a common history into one with two branches


Consider a repository which was duplicated onto another location. Both the original and copy received new commits, but they share the same past history of commits.

   ./dirA                          ./dirB

   * D: new commit                 * F: new commit
   |                               |
   * C: new commit                 * E: new commit
   |                               |
   * B: last common commit         * B: last common commit
   |                               | 
  ...                             ...
   |                               |
   * A: initial commit             * A: initial commit

How can I combine both so that all the common commits are preserved (including dates) and from the diverging commit forward the history is kept on two different branches?

   ./combined

   * D <dirA>  * F <dirB>
   |           |
   * C         * E: new commit
     \       /
      \    /
       \ /
        V 
        * B: last common commit
        |
       ...
        |
        * A: initial commit

Solution

  • If the commits are actually the same (e.g: both commits B have the same hash) :

    just put both histories in one common repo, and choose how you want to name your branches :

    • option 1: update dirA with commits from dirB :
    cd dirA
    git remote add other ../dirB  # <- dirB is a path on the same local computer correct ?
                                  # please update your question if this weren't the case
    
    git fetch other
    
    # you should now have all commits from dirB available as commits in A,
    # and branches in repoB available as named remote banches `other/*` :
    git branch masterB other/master
    git branch wokrBranch <E>
    
    • option 2: do not alter dirA or dirB, join them in a separate repo:
    # clone one of your directories, and add the second one as a remote:
    git clone dirA mergeRepo
    cd mergeRepo
    git remote add other ../dirB
    
    # then same as above:
    git fetch other
    git branch masterB other/master
    
    # with the above commands: 'dirA' is 'origin', 'dirB' is 'other'
    
    # inspect the history ...
    # if satisfied with the result, you can push new branches:
    git push origin masterB