代码之家  ›  专栏  ›  技术社区  ›  Janus

Git:追溯引入多个合并

git
  •  4
  • Janus  · 技术社区  · 14 年前

    我试图通过(追溯性地)将它应用到一个我跟踪一段时间的远程代码库的项目中来学习Git。 当我把所有的东西都放进Git时,我只做了一个 remote 对所有外部版本进行分支并启用我的版本 master ,因此当前我的存储库如下所示:

    master: A0---A1.0--A1.1--A2.0--A2.1-....
              \                
    remote:    B1----------B2-----------....
    

    我的问题是:如何追溯地告诉Git发生的合并,使存储库看起来像这样(不应该更改任何代码):

    master: A0---A1.0--A1.1--A2.0--A2.1-....
              \ /           / 
    remote:    B1----------B2-----------....
    

    标准git免责声明:上述操作不会影响任何已发布的历史记录:)

    编辑:以下是我如何使用Kevin建议的移植物来完成的:

    首先,我手工创建了.git/info/grafts,如下所示(所有条目都是sha1的):

    A1.0 A0 B1
    A2.0 A1.1 B2
    

    然后,在检查了情况是否良好(Gitx)后,我跑了 git filter-branch 没有参数。

    Filter-branch 将使嫁接永久化,并存储对原始承诺的引用 refs/originals/... 允许您通过退出 git reset --hard refs/originals/refs/heads/master . 因为一切看起来都很好,我把所有的剩菜都去掉了,如下:

    rm .git/info/grafts
    rm .git/refs/originals
    

    如果你有垃圾收集,你需要做 git update-ref -d refs/originals/refs/heads/master 相反。

    3 回复  |  直到 8 年前
        1
  •  3
  •   Lily Ballard    14 年前

    听起来像你想要的 grafts . 您可以为您想要的新合并创建嫁接(记住在嫁接中包含原始父级!)当一切都好的时候,用 git filter-branch (阅读手册!)把它放在石头里烤。

        2
  •  2
  •   Cascabel    14 年前

    您完全可以通过执行一个交互式的REBASE来伪造这一点,指定您要编辑所有这些提交,并用合并提交修改它们:

    git rebase -i A0 master
    # change the lines for A1.0 and A2.0 to "edit"
    # git stops at A1.0
    git merge --no-commit --strategy=ours B1     # the SHA1 of B1, of course
    git commit --amend
    git rebase --continue
    # git stops at A2.0
    git merge --no-commit --strategy=ours B2
    git commit --amend
    git rebase --continue
    

    每次你停下来,你都在技术上融合,但是 ours 策略,保持当前提交的所有内容。这个 --no-commit 通知Git在提交之前停止。然后,您将当前提交(这基本上意味着替换)修改为合并,而不是像通常那样使合并成为单独的提交。塔达!A1.0已被替换为具有相同树的新提交,但有一个附加的父级。 commit --amend 给你一个编辑信息的机会;你可能想这样做,留下一些你所做的记录。

        3
  •  2
  •   Red Riding Hood    8 年前

    我知道这是一个老问题,但有一种更新的执行方法(从Git 1.6.5开始)。

    git replace --graft <commit> <parent1> <parent2>
    

    哪里是sha hashes