Merge two Git repos and keep the history

后端 未结 3 947
眼角桃花
眼角桃花 2020-12-04 22:41

I want to extend on another question I had: Merge two Git repositories and keep the master history

I have succeeded in merging 2 different repo\'s into one repo. I n

相关标签:
3条回答
  • 2020-12-04 23:21

    There are two options in git rebase that should be of interest in your case:

    p
    --preserve-merges
    

    Recreate merge commits instead of flattening the history by replaying commits a merge commit introduces.

    --committer-date-is-author-date 
    

    (from git am)

    By default the command records the date from the e-mail message as the commit author date, and uses the time of commit creation as the committer date. This allows the user to lie about the committer date by using the same value as the author date.

    Test if the second rebase doesn't yield a better result with:

    git rebase -p --committer-date-is-author-date RepoA/master
    
    0 讨论(0)
  • 2020-12-04 23:34

    This answer suggests a different way to use RepoB as the active repo, and still have access to RepoA history :

    use git replace

    # start with a regular clone of the active repo :
    $ git clone RepoB
    
    # add repoA as a remote :
    $ git remote add -f history https://github.com/DimitriDewaele/RepoA
    
    # get hash of *initial* commit on repoB :
    $ git log --oneline origin/master | tail -1
    abcdef Initial commit
    
    # get hash of last commit on repoA :
    $ git log --oneline history/master | head -1
    12345 Merge branch 'develop'
    
    # use 'git replace' to tell git to stitch histories in the log :
    $ git replace abcdef 12345
    

    Note : this operation is done on your machine, not on the remote repositories, so should be repeated on all new clones.

    Variant :

    You may push RepoA:master to RepoB under a new name (e.g : RepoB:history/master), then you can use git replace abcdef history/master, on commits which are all stored in RepoB.

    0 讨论(0)
  • 2020-12-04 23:41

    As you've discovered, rebase isn't the command you want to use to stitch histories together (because it actually rewrites history). Early Git had a feature (hack) designed specifically for what you're trying to do: graft points. Even better, since 1.6.5 you can use git replace --graft instead:

    git checkout master
    git replace --graft $(git log RepoB/master --format=%H | tail -1) HEAD
    git replace --graft $(git log RepoA/master --format=%H | tail -1) RepoB/master
    git reset --hard RepoA/master
    

    (git log RepoA/master --format=%H | tail -1 returns the initial commit from RepoA)

    Technically you could skip the first replace if you don't actually have anything of value yet in master, yielding just history with RepoB + RepoA.

    These commands create entries in refs/replace/* that can be pushed and pulled to share your revised history with others. Or, if you don't care about preserving the SHAs of RepoA/RepoB, you can make the replacements permanent by running git filter-branch --all to produce a "real" set of commits of the desired lineage.

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