Git 如何创建反映另一个(发散)分支状态的提交?

Git 如何创建反映另一个(发散)分支状态的提交?,git,branch,commit,Git,Branch,Commit,我想进行提交并将其复制到存储库中的其他位置 当前情况: A--B--C--D (branch1) \ E--F (branch2) A--B--C--D--F'(branch1) \ E--F (branch2) 理想情况: A--B--C--D (branch1) \ E--F (branch2) A--B--C--D--F'(branch1) \ E--F (branch2) F保留在存储库中是很重要的。我不想重

我想进行提交并将其复制到存储库中的其他位置

当前情况:

A--B--C--D (branch1)
    \
     E--F (branch2)
A--B--C--D--F'(branch1)
    \
     E--F (branch2)
理想情况:

A--B--C--D (branch1)
    \
     E--F (branch2)
A--B--C--D--F'(branch1)
    \
     E--F (branch2)
F保留在存储库中是很重要的。我不想重写历史,因为F可能是公共的

F和F'表示的存储库(源代码)的状态应该完全相同。是的,引入的C和D可能会丢失


我不想在D之上重放E和F。我已经研究了
樱桃选择
重基
,但它们似乎删除了原始提交,或者只是在目标之上重放更改。

假设您已签出
D

$ git rm -r .
$ git archive F | tar xf -
$ git add .
$ git commit -m "Duplicate tree of commit F"
第一步将删除所有当前文件,然后您将获取一个存档(
git archive
默认为
tar
,h/t为Marc François),并立即将其放入您的工作副本中。添加所有内容并提交

这在我的系统上进行了一个非常小的测试,因此需要彻底测试。

一个解决方案 我有点生疏了,但我相信下面的方法可以奏效:

git checkout branch2
git update-ref --no-deref HEAD branch1 # make HEAD to point at the tip of branch1, but keep the working tree from branch2
git checkout branch1 # reattach HEAD to branch1
git commit -m "Some commit message for F'"
回顾过去,我认为torek的方法更简单、更安全。特别是

最低工作示例
这一点是我第一次评论时遗漏的一个关键点:

[F]和F'表示的存储库(源代码)的状态应该完全相同。是的,引入的C和D可能会丢失

在本例中,从git checkout branch2开始,您可以使用,但有一个更简单,甚至更简单:

$ git rm -r .
$ git checkout <hash-of-F> -- .
$ git commit
因为这个
git读取树
相当于删除和替换


您可以使用名称
branch1
而不是commit
F
的散列,直到
branch1
本身移动并且不再指向commit
F

这样我们就很清楚了:您希望
F
F'
具有相同的工作树,但具有不同的父级(
E
vs
D
)?@StephenNewell是的,没错。@Jubobs:啊,对不起,我误解了这个问题!将删除注释。cherry pick和rebase都不会删除原始提交。除非您另有指定,否则它似乎始终是tar文件@马克·弗朗索瓦——谢谢。我现在意识到我的评论并不清楚,因为我真正担心的是在非Linux平台上默认使用zip。