如何创建一个镜像另一个(发散)分支状态的提交?

时间:2018-04-12 20:34:41

标签: git branch commit

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

现状:

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.我已经查看cherry-pickrebase,但似乎他们删除了原始提交或只需重播目标顶部的更改。

3 个答案:

答案 0 :(得分:5)

这一点是一个关键项目,我在第一次评论时错过了:

  

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

在这种情况下,从git checkout branch2开始,您可以使用Stephen Newell's answer,但有一个更简单,而且更简单:

$ git rm -r .
$ git checkout <hash-of-F> -- .
$ git commit

通过删除索引中的所有内容(并从工作树中删除它)来确保先前提交中没有遗留文件,然后从提交F中提取所有内容到索引和工作树中,准备好承诺。

您可以使用以下步骤缩短这一步:

$ git read-tree -m -u <hash-of-F>
$ git commit

因为git read-tree执行了与删除和替换等效的操作。

您可以使用名称branch1代替提交F的哈希值,直到branch1本身移动,不再指向提交F

答案 1 :(得分:2)

假设您已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)并立即将其放入您的工作副本中。添加所有内容并提交。

这在我的系统上的非常小测试中有效,所以要彻底测试。

答案 2 :(得分:2)

一种解决方案

我有点生疏,但我相信以下可以解决这个问题:

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的方法更简单,更安全。特别是update-ref can easily be misused

最低工作示例

# setting things up (output omitted)
mkdir mwe && cd mwe
git init
echo A > README
git add README
git commit -m A
git branch -m branch1
echo B >> README 
git commit -a -m B
echo C >> README 
git commit -a -m C
echo D >> README 
git commit -a -m D
git checkout -b branch2 branch1~2
echo E >> README 
git commit -a -m E
echo F >> README 
git commit -a -m F

# now...
$ git update-ref --no-deref HEAD branch1
$ git checkout branch1
M   README
Switched to branch 'branch1'
$ git commit -a -m "F'"
[branch1 36b29b2] F'
 1 file changed, 2 insertions(+), 2 deletions(-)
$ git show
commit 36b29b21cc014ee1ec73ac5dd80a4ad834ee282a (HEAD -> branch1)
Author: xxxxxxxxxxxx
Date:   xxxxxxxxxxxxx

    F'

diff --git a/README b/README
index 8422d40..04bc76d 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
 A
 B
-C
-D
+E
+F