给定以下提交图:
A--B--C (origin/foo)
D--E (foo)
我想实现这个:
A--B--C--F (foo origin/foo)
F
是一个 rebase 提交,它基本上包含我本地历史的更改D--E
并撤消/清空它之前的所有其他内容。最终用我的本地状态 (foo@{E}
) 替换整个远程 HEAD 状态,只是将历史记录更改为基于远程提交的基础。我的环境不允许简单的git push --force
,我必须保持远程提交。
我试过
git rebase -X theirs origin/foo
(使用倒置策略选项),但它保留了远程的所有非冲突更改,我想在同一个差异中删除它们。 git rebase -s theirs origin/foo
没有按预期工作 (git: 'merge-theirs' is not a git command. See 'git --help'.
).
我可以
git revert
在做变基之后每一个其他提交,然后在提交之前将它们压缩成一个,但我正在寻找一个更优雅的解决方案,如果可能的话。
对于更改应用部分,如果
git cherry-pick E
是two提交,您可以尝试
D-E
。如果它们代表很多提交,首先在它们之间创建补丁,
git diff --binary D E > patch.diff
然后应用补丁,
git apply -3 patch.diff
这两种方式都可能存在冲突。
最终用我的本地状态 (foo@{E}) 替换整个远程 HEAD 状态
你的意思是想让F的文件和E的一模一样?如果是这样,应用 D 和 E 之间的更改将不起作用。相反,您需要创建一个提交,其树与 E 的树相同,其父级为 C。
# Replace C and E with their sha1 values
git commit-tree -p C -m "some message" E^{tree}
它创建一个提交并打印它的 sha1 值。然后更新
foo
以指向新的提交。
git update-ref refs/heads/foo $newcommit
如果
foo
当前已签出,您还可以运行 git reset $newcommit --hard
.