以非交互方式查找合并提交的正确父级

时间:2014-12-30 11:15:57

标签: git git-svn git-filter-branch

我正在准备一个svn2git迁移,虽然https://github.com/nirvdrum/svn2git非常有用,但我仍然得到了几个恶作剧。我已经能够清理它们中的大多数,但仍然有一个。我的历史看起来像这样:

A1 - B1 - C1 - E1 - F1
             \
A2 - B2 - C2 - D1
除了额外的子目录级别外,

A1-C1和A2-C2是相同的。 A2-C2实际上是svn迁移和之前git-filter-branch操作的工件,我确信这一点。 D1是一个标记为release_2_0_4的合并提交。

我想摆脱A2-C2。我看到两种方法:

  1. Untag D1,标签C1,reflog过期和垃圾收集。噗! A2-C2消失了。
  2. 我也可以重写D1的父母,所以它只有C1作为父母,有点git-filter-branch魔法。
  3. 可以使用第一种方法,因为C1和D1的文件内容是相同的(用git diff C1 release_2_0_4检查),但是我会丢失提交日期,作者和消息。

    第二种方法是:

    git filter-branch --tag-name-filter cat --parent-filter 'test $GIT_COMMIT = [sha of release_2_0_4] && echo "-p [sha of FIRST parent of release_2_0_4]" || cat' -- --all

    我已经使用硬编码SHA以手动方式尝试了它,它可以工作。但我需要在不知道SHA的情况下编写脚本。

    我知道如何找到D1的父母,可以使用插入符号来引用它们:release_2_0_4^1release_2_0_4^2(发现在这里:Get parents of a merge commit in git),但我不确定我怎么能找出哪个是哪个。我在脚本中执行此操作,而不是以交互方式执行此操作,而其他git-filter-branch操作可能会更改SHA哈希值,因此我需要找到一种方法来确定我需要的两个提交中的哪一个。我唯一的线索是C1有2个子提交,而C2只有一个子提交。

    总结一下,我的问题是:

    • 如何找到[sha of FIRST parent of release_2_0_4]
    • 如何将它放在Bash脚本中而不会与单引号,双引号,变量扩展等混淆?

    PS:我不需要担心上游,没有任何可能包含此代码的git repos被认为是官方的,直到我为svn2git迁移开绿灯才会有。

1 个答案:

答案 0 :(得分:1)

我发现没有可靠的方法可以做到这一点,因为git认为每个父级都是相等的,它只是以它获取它们的顺序使用它们。

所以我最终手动完成,如上所述。