关于Git-Rebase:如何组合两个不相关的Git存储库,保留历史

How to combine two unrelated git repositories, preserving history

我不太了解吉特。- -

背景

我有两个不相关的基于Git的文档存储库,我想将它们合并到一个存储库中。我想保留原始的时间戳(可追溯到2005年)和个人文件历史记录。这两个repo不包含分支、文件夹,并且在文件命名方面没有重叠。

在ASCII语言中,它看起来如下:

1
2
REPO A    |-------------------------|
REPO B                    |===============|

其中重叠表示时间。

目标

我的目标是"压缩"重叠的时间戳,使两个回购看起来像一个完整的历史:

1
REPO A+B  |-------------------==--=---============|

我试过什么

再说一次,我不太了解吉特,所以我可能把事情搞砸了。

首先,我尝试将较新、较小的repo添加为较大、较旧的repo的远程,获取更改,并提交结果。我以所有新回购的变化在旧回购之后集中在一个分支中结束:

1
2
MERGE  |-------------------------                 -|
                                 \===============/

接下来,我尝试重新平衡(使用--committer-date-is-author-date,我认为这是可行的,但最终我得到了一个很长的提交历史,它只是将两个回购协议堆叠在一起。

1
REBASE |-------------------------===============|

我还没有找到一种方法来"重放"合并的历史。我真的希望莱巴斯能成为答案。

我看过的答案

  • 合并两个Git存储库而不破坏文件历史记录(1)
  • 不更改提交时间戳的git rebase(2以上,没有"zipper"历史记录)
  • 如何将两个独立的无关Git存储库组合成一个具有单个历史时间线的存储库
  • 组合不相关的Git存储库保留历史/分支


虽然@codewizard的回复很有用,但这种方法并没有按照我想要的方式保留时间戳。它确实把我引向了一个兔子洞,帮助我找到了解决办法…

  • 创建新的空白存储库

    1
    git init
  • 添加旧存储库并将其作为远程存储库获取

    1
    2
    git remote add -f oldRepoA ../oldRepoA
    git remote add -f oldRepoB ../oldRepoB
  • 按时间戳和哈希导出组合的提交历史记录,将输出通过管道发送到sort,通过cut丢弃时间戳,然后将按时间排序的哈希列表通过管道发送到xargs,后者运行shell脚本为每个哈希导出一个补丁,然后立即将补丁应用到新的repo。

    1
    2
    3
    4
    git log --all --oneline --format="%at %H" | sort | cut -c12- |
        xargs -I {} sh -c
            'git format-patch -1 {} --stdout |
             git am --committer-date-is-author-date'
  • --committer-date-is-author-date是保持原始时间戳的关键。也许有更好的方法来完成这项工作,但是对于我的用例来说这已经足够好了!


    你必须写一个脚本来完成它。

    如何做到这一点

  • 获取每个分支的所有提交时间戳的列表

    1
    2
    3
    # print out the commits time stamp & sha-1 of each commit
    # do it for all your branches
    git log --oneline --format="%at %H"

    enter image description here

  • 将这两个列表组合在一起,并使用任何排序工具(sublime、unix sort等)按时间戳对它们进行排序。

  • 签出新分支开始文件中的第一次提交

    1
    git checkout <first commit id>

    enter image description here

  • 从此提交开始创建新分支

    1
    git checkout -b <new_branch_name>
  • 循环所有其他提交,并使用cherry pick将它们引入您的分支(脚本)

    1
    git cherry-pick <next commit id>