在 git 中强制合并的最佳方法是什么?

问题描述 投票:0回答:2

我有一个带有开发分支和生产分支的项目。最近,我一直在开发中开发一系列新功能,因此我已经大约两周没有合并到生产中了。但与此同时,生产中还存在一些需要修复的错误。

在很大程度上,我能够在开发中进行修复,并将它们挑选到生产中。然而,有时我需要手动修复生产,因为两个分支中的修复有很大不同。重点是,这两个分支自从分裂以来已经出现了相当大的分歧。

现在我想将所有开发投入生产。我不关心自分裂以来在生产中保留任何提交,我只是希望生产看起来与开发完全一样。 [编辑:我希望生产看起来与 dev 自分裂以来一模一样,但不想在分裂之前重写历史]但是,当我尝试合并时,我遇到了数十个冲突,我不想通过以下方式解决这些冲突手。

在 git 中强制合并的最佳方法是什么?我可以将生产更改恢复到拆分,然后快进到开发分支吗?

git merge
2个回答
28
投票

您可以将您的开发分支推送到主存储库生产分支上:

git push --force upstream-remote dev:production
如果您使用的是默认克隆,

upstream-remote
可能只是
origin

更新了修改后的问题:

你可能不想

revert
在 git 意义上,但是,是的,这或多或少是你想做的。类似的东西

git checkout -b merge <split hash>
git merge dev
git push --force origin merge:production

是您想要保留的最后一次生产提交。


-3
投票

首先,虽然这不是关于如何实际强制推送的建议,但它直接满足了OP的愿望:“我希望生产自分裂以来看起来与开发完全一样,但不想重写分裂之前的历史”。事实上,你根本不需要重写历史!

如果您希望将代码从一个分支强制到另一个分支而不重写历史记录,这是一种很棒的方法。

这是我们推荐的:(

main
这里是生产分支)

git checkout dev
git merge -s ours main

然后创建从

dev
main
的合并/拉取请求,或者将 dev 普通合并回 main:

git checkout main
git merge

按照OP的要求,这会将

main
中的所有内容替换为
dev
中的当前内容。它通过记录
main
dev
的合并来实现此目的,而不实际更改
dev
中的任何内容。但由于
main
存在于
dev
的合并历史记录中,因此从
dev
main
的拉取请求被视为快进合并。

整个过程看起来是这样的:

$ git adog
* 890f8d9 (dev) dev continues further with better code
* 3ce948b dev branches from main with great code
| * d5dbf64 (HEAD -> main) main continues further
|/
* 6e24a88 main continues
* f389591 Start of main branch

$ git checkout dev
Switched to branch 'dev'

$ git merge -s ours main
Merge made by the 'ours' strategy.

$ git checkout main
Switched to branch 'main'

$ git merge dev
Updating d5dbf64..f28fddb
Fast-forward
 tmp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git adog
*   f28fddb (HEAD -> main, dev) Merge branch 'main' into dev, keeping only contents of dev.
|\
| * d5dbf64 main continues further
* | 890f8d9 dev continues further with better code
* | 3ce948b dev branches from main with great code
|/
* 6e24a88 main continues
* f389591 Start of main branch

注意清晰的历史记录,这对于后来的开发人员来说很容易遵循。

这个解决方案比当前社区对此问题的共识更安全、更干净。它根本不需要

git rm -rf .
git checkout dev -- .
。两个分支在任何时候都没有被完全清除,并且 git 历史记录清楚地显示了故意覆盖发生的位置。请务必在提交注释中提及这是一个 merge -s 我们的提交,例如,在提交消息中说“仅保留 dev 的内容”。

我知道在一种情况下

git merge -s ours main
会失败:那就是当
dev
位于直接下游
main
时,例如如果您尝试执行 -s ours 合并两次:

$ git adog
*   f28fddb (HEAD -> dev) Merge branch 'main' into dev, keeping only contents of dev.
|\
| * d5dbf64 (main) main continues further
* | 890f8d9 dev continues further with better code
* | 3ce948b dev branches from main with great code
|/
* 6e24a88 main continues
* f389591 Start of main branch

yoder@MSOE-PF3TQZ3S MINGW64 ~/Box/Josiah/msoe/class/s/swe2410/24s2/Labs/tmp (dev)
$ git merge -s ours main
Already up to date.

在这种情况下,解决方案很明确——只需继续执行其他步骤,它们就会按预期工作。

dev
已经被认为是主分支的延续,因此普通的合并将完全满足您的要求。

© www.soinside.com 2019 - 2024. All rights reserved.