【问题标题】:How to concatenate two git histories?如何连接两个git历史?
【发布时间】:2010-07-10 15:09:56
【问题描述】:

我有两个切向相关的 git 存储库。即,一个的内容是另一个的前身。我想以某种方式将存储库 A 的完整历史记录添加到存储库 B,以便 A 的尖端成为存储库 B 的第一个变更集的父级?两者的历史都是相当线性的。

这可能吗?

【问题讨论】:

    标签: git repository history


    【解决方案1】:

    您可以尝试使用移植文件 (.git/info/grafts),您可以在其中覆盖提交的父级(例如 projectB 中的第一个 projectA 的父级最新)

    有关此操作的更多信息,另请参阅“What are .git/info/grafts for?”和“How to prepend the past to a git repository?”。


    skaleecomments 关于文章“Git: Grafting repositories”(来自 SO 用户 Ben Straub)的具体示例。

    现在我们要做的是更改“nuevo”存储库(“New commit #1”)中的第一个提交,使其父级是“旧”存储库(“旧 #3”)中的最后一个提交.是时候来点巫术了:

    git fetch ../old master:ancient_history
    

    Git 允许您从任何其他 git 存储库中获取,无论此存储库是否与它相关!杰出的!这给我们留下了这个:

    请注意我们如何将旧的 master 分支重命名为 Ancient_history。如果我们不这样做,git 会尝试将两者合并,并且可能会厌恶地放弃。

    现在我们还有一个问题。
    这两棵树没有连接,实际上 git pull 甚至根本不会得到 Ancient_history 分支。我们需要一种方法在两者之间建立联系。

    Git 有一个叫做 Graft 的工具,它基本上伪造了两个提交之间的父链接。
    要制作一个,只需在 .git/info/grafts 文件中插入一行,格式如下:

    [ref] [parent]
    

    这两个都需要是相关提交的完整哈希。所以让我们找到它们:

    $ git rev-list master | tail -n 1
    d7737bffdad86dc05bbade271a9c16f8f912d3c6
    
    $ git rev-parse ancient_history
    463d0401a3f34bd381c456c6166e514564289ab2
    
    $ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \
           463d0401a3f34bd381c456c6166e514564289ab2 \
           > .git/info/grafts
    

    (在一行中,suggested by ssokolow

    echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts 
    

    那里。现在我们的历史看起来像这样:

    克隆这个 repo 会导致:

    哎呀。事实证明,嫁接只对本地存储库生效。我们可以通过明智地应用 git fast-import 来解决这个问题:

    $ git fast-export --all > ../export
    
    $ mkdir ../nuevo-complete
    
    $ cd ../nuevo-complete
    
    $ git init
    
    $ git fast-import < ../export
    git-fast-import statistics: [...]
    

    (在一行中,suggested ssokolow

    git filter-branch $(git rev-parse ancient_history)..HEAD 
    

    这有效地将我们的“假”历史链接转换为真实链接。
    所有的工程师都必须从这个新的存储库中重新克隆,因为哈希值都会有所不同,但对于不停机和完整的历史记录来说,这是一个很小的代价。

    作为Qix cmets below:

    fast-import 似乎只是导入 git 信息,但没有检查任何内容。
    git init 最初将您置于 master 位置,因此 您需要一个 git reset --hard HEAD 来实际检查文件在你fast-import之后。

    【讨论】:

    • 对我来说工作得很好,感谢 VonC,没想到会这么简单。
    • 然后您可以使用git filter-branch 重写历史以使移植带来的永久化......但这会重写历史。
    • 简短而简洁的文章真正帮助我了解什么是移植物以及如何逐步加入这些历史:ben.straubnet.net/post/939181602/git-grafting-repositories
    • @skalee 好文章。我已经在答案中包含了主要命令。
    • @Qix 好点。我已将您的评论包含在答案中以提高知名度。
    猜你喜欢
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 2015-06-29
    • 2016-01-11
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 2021-10-27
    相关资源
    最近更新 更多