如何从master合并到项目中,丢弃所有项目提交?

时间:2012-12-10 12:00:28

标签: git

我有(或者我的目标是!)像这样的回购:

Master *-----*--*----------C---
        \                   \
Project1 \-*-------A----B----M2---A'--B'---
          \              \             \
Project2   \----------*---M1------------M2---

我想合并 M2 ,但我希望 A B 完全忽略。然后,我将手动(例如,挑选)重新创建 A' B' ,如果有必要,可以在主设备的新更改之上。

Project2基于Master,但合并了Project1的更改。

期望的结果:

  1. 我希望点 M2 在文件方面与 C 完全相同。

  2. 我需要Project1拥有自己的线性历史记录,以便Project2可以从中合并。

  3. 上下文:Master是Drupal的主要代码库。 Project1是我用来维护特定补丁的分支,我想与几个项目共享。 Project2(和许多其他人)从Project1合并。

    我考虑过:

    1. git merge -s recursive -X theirs master问题在于AFAIK如果发生冲突,它只会选择theirs。因此,如果A的变化不冲突,它将出现在 M2 ,这意味着A'将是不完整的。

    2. git revert B..A ; git merge C这会有效但会给我留下一个混乱而漫长的历史。

    3. git merge -s ours,但似乎没有git merge -s theirs

    4. 我不想git reset --hard C因为这会(我认为)打破了将Project1合并到Project2的可能性。另一种方法是将Project1重新绑定到C,但同样,这意味着我无法合并到Project2中。

2 个答案:

答案 0 :(得分:2)

我会反对你的计划 - 你试图欺骗git。 Git不喜欢被愚弄。你也在“伪装”你的历史。 M2,A'和B'都应该是一次提交 - 合并。

但如果你想继续,请这样做:

git merge --no-commit C
rm -rf *
git checkout C .
git commit

如果您要保留任何gitignored文件,请在rm之前备份它们,然后再恢复它们。

或者,您也可以(实际上更清洁)

git checkout C
git symbolic-ref HEAD refs/heads/Project1
git update-ref MERGE_HEAD C
git commit

答案 1 :(得分:1)

这可以通过“plumbing”命令来完成:

$ git checkout Project1
$ git diff HEAD..master | patch -p1 
$ git add -A .
$ git commit-tree `git write-tree` -p master -p Project1 \
      -m "Merge to clean Master at v1.2"
0c5290081989cc28ff3977fbfe3951db7b7778b0
$ git reset --hard 0c5290081989cc28ff3977fbfe3951db7b7778b0

git diff HEAD..master会告诉我如何在一个大的地方( B )和我想去的地方( C )补丁,补丁当然会应用它。

git add -A .会将工作树中的所有更改添加到索引中。

然后我们使用下一行创建一个合并提交:git-write-tree从索引创建一个新的树对象,并将其SHA1作为参数输出到git commit-tree,这将创建一个提交它有两个父母,Project1的当前负责人( B )和主人( C ),并给它一个合适的信息。

Git将创建提交对象,但它不会更新任何分支以使用此提交。最后一行告诉git我们希望将当前分支Project2推进(快速转发)到它生成的提交SHA1。

如果需要,你可以从那里重新创建(例如可以尝试使用樱桃挑选)补丁A'和B'。