【问题标题】:How to combine two unrelated git repositories, preserving history如何组合两个不相关的 git 存储库,保留历史记录
【发布时间】:2016-04-18 01:44:05
【问题描述】:

我不太了解 git。 :-/

背景

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

在 ASCII 领域,它看起来像这样:

REPO A    |-------------------------|
REPO B                    |===============|

重叠表示时间。

目标

我的目标是“压缩”重叠的时间戳,使两个存储库看起来像一个单一的、完整的历史记录:

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

我的尝试

再说一次,我不太了解 git,所以我可能搞砸了。

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

MERGE  |-------------------------                 -|
                                 \===============/

接下来我尝试了变基(使用--committer-date-is-author-date),我认为这可行,但我最终得到了一个很长的提交历史,只是将两个存储库堆叠在一起。

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

我还没有找到“重播”合并历史的方法。我真的希望 rebase 能成为答案。

我看过的答案

【问题讨论】:

  • 如果使用 merge 方法,git log --date-order 将按照您的要求显示按提交时间排序的提交,git log --date-order --graph 将分支树显示为好吧。

标签: git git-rebase


【解决方案1】:

虽然@codeWizard 的回复很有帮助,但这种方法并没有按照我想要的方式保留时间戳。它确实让我陷入了一个兔子洞,但它帮助我找到了解决方案......

  1. 创建一个新的空白存储库

    git init
    
  2. 将旧仓库作为远程仓库添加和获取

    git remote add -f oldRepoA ../oldRepoA
    git remote add -f oldRepoB ../oldRepoB
    
  3. 通过时间戳和哈希导出合并的提交历史,将输出通过管道传输到sort,通过cut丢弃时间戳,然后将按时间排序的哈希列表通过管道传输到xargs,它运行一个shell脚本来导出为每个单独的哈希打补丁,然后立即将补丁应用到新的 repo。

    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 是保留原始时间戳的关键。可能有更好的方法来做到这一点,但这对于我的用例来说已经足够好了!

【讨论】:

  • @CodeWizard 的建议发生了什么?每个cherry-pick都将提交日期设置为当前日期时间?我是trying to do something similar to you,但是存储库是相似的,所以我不知道它是否可以工作。
  • 是的,这最终导致X: already exists in working directory Patch failed at 0001。这是否适用于具有多个分支的存储库,例如 masterdevelop
【解决方案2】:

您必须编写一个脚本来执行此操作。

怎么做

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

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

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

  3. 从文件中的第一个提交开始签出新分支

    git checkout <first commit id>
    

  4. 从此提交开始创建新分支

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

    git cherry-pick <next commit id>
    

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多