How to merge several Git repos into one and interleave histories

后端 未结 2 550
醉话见心
醉话见心 2021-01-11 22:44

My situation is that I have two Git repositories that I need to merge into a single repository (there are actually more repos, but I can start with two).

The two rep

相关标签:
2条回答
  • 2021-01-11 23:25

    The solution turned out to be much more involved than I had hoped for. It involves manipulating and combining the output of two (or more) git fast-export streams, and importing them into a new repository using git fast-import.

    In short, a new fast-import stream is generated by traversing two input streams, and switching back-and-forth between them based on a date-sorted log from the main branches.

    I have implemented the solution in a Python script called join-git-repos.py, that I put in a GitHub repository here.

    0 讨论(0)
  • 2021-01-11 23:32

    First, move everything in repo A to the subdirectory A/. Nothing fancy, just git mv. This preserves all branches and tags and commit IDs in A.

    Then use git subtree to make the master branch of B a subtree of A in directory B/.

    git subtree add -P B/ <remote for B> master
    

    And you're done.


    If you want old release tags on A to also reflect what would have been in B at that time... oy. You can do this without messing up your history too badly by merging B into A just before each release tag.

    You have this.

              * - * - *           * - * - * branch
        v1   /         \    v2   /
    * - * - * - * - * - * - * - * - * - * master
                                       /
      * -- * ---- * - * - * --------- *
    

    The bottom line of commits is B. B's commits are laid out so they line up in time with A's.

    And you want something like this.

              * - * - *           * - * - * branch
        v1   /         \    v2   /
    * * * - * - * - * - * * * - * - * - * master
      |                   |            /
      * -- * ---- * - * - * --------- *
    

    This has merged B into A just before each release tag. This avoids making up an artificial history of A and B being developed together.

    I don't know how to do that in an automated fashion. The problem is rebase does not preserve tags, only merges. So adding the merge commit to v1 will lose the v2 tag and I'm not sure how to identify what the original commit of a rebased commit is.

    Good luck.

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