我有两个分支,电子邮件和分期。分期是最新的一个,我不再需要旧的更改在电子邮件分支,但我不想删除他们。
我只想将所有staging的内容转储到电子邮件中,以便它们都指向同一个提交。这可能吗?
我有两个分支,电子邮件和分期。分期是最新的一个,我不再需要旧的更改在电子邮件分支,但我不想删除他们。
我只想将所有staging的内容转储到电子邮件中,以便它们都指向同一个提交。这可能吗?
当前回答
警告:这将删除电子邮件分支上的所有提交。这就像删除电子邮件分支,并在登台分支的头部重新创建它。
最简单的方法是:
//the branch you want to overwrite
git checkout email
//reset to the new branch
git reset --hard origin/staging
// push to remote
git push -f
现在电子邮件分支和分期是相同的。
其他回答
你可以使用“ours”合并策略:
$ git checkout staging
$ git merge -s ours email # Merge branches, but use our (=staging) branch head
$ git checkout email
$ git merge staging
编辑2020-07-30:
关于这个问题和可能的解决方案,我想了更多。如果您绝对需要以正确的顺序合并父节点,需要通过单个命令行调用来执行此操作,并且不介意运行管道命令,您可以执行以下操作:
$ git checkout A
$ git merge --ff-only $(git commit-tree -m "Throw away branch 'A'" -p A -p B B^{tree})
这基本上就像(不存在的)合并是他们的战略。 您可以在演示存储库的管道分支中找到生成的历史记录
与-s开关相比,不是很容易读懂,也不是那么容易记住,但它做到了。结果树与分支B相同:
$ git rev-parse A^{tree} B^{tree} HEAD^{tree}
3859ea064e85b2291d189e798bfa1bff87f51f3e
0389f8f2a3e560b639d82597a7bc5489a4c96d44
0389f8f2a3e560b639d82597a7bc5489a4c96d44
编辑2020-07-29:
关于-s我们的和-X我们的(后者相当于-s递归——策略选项我们的)之间的区别,似乎有很多困惑。下面是一个小示例,展示使用这两种方法得到的两个结果。我还建议阅读(Git合并)何时使用“我们的”策略,“我们的”选项和“他们的”选项的问题和答案?
首先,设置一个带有2个分支和3个提交的存储库(1个基本提交,每个分支1个提交)。您可以在GitHub上找到示例存储库
$ git init
$ echo 'original' | tee file1 file2 file3
$ git commit -m 'initial commit'
$ git branch A
$ git branch B
$ git checkout A
$ echo 'A' > file1
$ git commit -m 'change on branch A' file1
$ git checkout B
$ echo 'B' > file2
$ git commit -m 'change on branch B' file2
现在,让我们试试策略选项(不管我们用他们的还是我们的来解释):
$ git merge -X ours A
$ cat file*
A
B
original
我们最终合并了两个分支的内容(样本回购中的分支“strategy-option”)。将其与使用合并策略(在执行下一步之前重新初始化存储库或重置分支)进行比较:
$ git merge -s ours A
$ cat file*
original
B
original
结果是完全不同的(示例回购中的分支“merge-strategy”)。使用策略选项,我们得到两个分支的合并结果,使用策略,我们丢弃在另一个分支中发生的任何更改。
你还会注意到merge-strategy创建的提交实际上指向与“our”分支的最新提交完全相同的树,而strategy-option创建了一个新的,以前未见过的树:
$ git rev-parse A^{tree} B^{tree} merge-strategy^{tree} strategy-option^{tree}
3859ea064e85b2291d189e798bfa1bff87f51f3e
0389f8f2a3e560b639d82597a7bc5489a4c96d44
0389f8f2a3e560b639d82597a7bc5489a4c96d44
5b09d34a37a183723b409d25268c8cb4d073206e
OP确实要求“我不再需要[…]分支中的旧更改”和“所以我只想将[A]的所有内容转储到[B]中”,这是策略选项不可能做到的。使用“我们的”合并策略是众多可能性中的一种,但可能是最简单的(其他可能性包括使用Git的低级命令,如写树和提交树)。
警告:这将删除电子邮件分支上的所有提交。这就像删除电子邮件分支,并在登台分支的头部重新创建它。
最简单的方法是:
//the branch you want to overwrite
git checkout email
//reset to the new branch
git reset --hard origin/staging
// push to remote
git push -f
现在电子邮件分支和分期是相同的。
你想要的是这个(实际上与目前接受的答案完全相反):
git checkout email
git merge --strategy-option=theirs staging
它的作用是:
电子邮件分支文件现在将完全相同的分期分支 电子邮件分支的历史将被保留 分期分支的历史将被添加到电子邮件历史
作为附加价值,如果您不想要所有登台分支的历史记录,您可以使用squash将其总结为一条提交消息。
git checkout email
git merge --squash --strategy-option=theirs staging
git commit -m "Single commit message for squash branch's history here'
总之,第二个版本所做的是:
电子邮件分支文件现在将完全相同的分期分支 电子邮件分支的历史将被保留 单个提交将被添加到电子邮件分支的历史记录之上。这个提交将表示在暂存分支中发生的所有更改
其他答案似乎不完整。 我已经尝试了下面的全部,它工作得很好。
注意: 1. 为了安全起见,在尝试下面的操作之前,请先复制您的存储库。
细节: 1. 所有的开发都在开发分支中进行 2. Qa部门只是开发部门的翻版 3.有时,开发代码需要被移动/覆盖到qa部门
所以我们需要覆盖qa分支,从开发分支
第1部分: 使用以下命令,旧的qa已经更新到新的开发:
git checkout dev
git merge -s ours qa
git checkout qa
git merge dev
git push
最后一次推送的自动评论如下:
// Output:
// *<MYNAME> Merge branch 'qa' into dev,*
这个注释看起来是相反的,因为上面的序列看起来也是相反的
第2部分:
下面是意想不到的,新的本地提交在开发中,不必要的 所以,我们需要抛弃这些内容,保持开发者的原封不动。
git checkout dev
// Output:
// Switched to branch 'dev'
// Your branch is ahead of 'origin/dev' by 15 commits.
// (use "git push" to publish your local commits)
git reset --hard origin/dev
// Now we threw away the unexpected commits
第3部分: 验证一切如预期:
git status
// Output:
// *On branch dev
// Your branch is up-to-date with 'origin/dev'.
// nothing to commit, working tree clean*
这是所有。 1. 旧的qa现在被新的开发分支代码覆盖 2. 本地是干净的(远程源/dev是不受影响的)
我已经看到了几个答案,这是唯一的程序,让我解决没有任何冲突。
如果你想要在branch_old中对branch_new的所有更改,那么:
git checkout branch_new
git merge -s ours branch_old
git checkout branch_old
git merge branch_new
一旦应用了这四个命令,您就可以毫无问题地推送branch_old了