git - 恢复分支 A 上的提交,稍后将 merge 到 B。提交应该留在 B

标签 git git-merge gitversion

假设我在无效的分支 A 上进行了提交,而这应该在分支 B 上进行。
Commit 被推送,后来我发现了这个错误。

我知道分支 A 将很快 merge 到 B,我只想还原 A 上的提交并应用 B 上的提交。
分支 B 将在某个时候 merge 到 A,但要晚很多 - 至于现在,只需要在 B 上应用更改。

当我想避免通过 merge 在分支 B 上再次恢复时,正确的方法是什么?您可以假设 merge 将由另一个人执行,这很容易出错,只需将还原应用于 B。

最佳答案

没有魔法可以让更改被删除、 merge 到其他地方然后出现,接受这一点应该有助于理解实现所需最终状态所需的步骤。

考虑以下简化的历史,它与问题中描述的场景相匹配:

$ git log --all --decorate --oneline --graph
* 9eb80d9 (b) Some change added to b only
| * c297cb5 (a) Should be on b, but not a
|/
* 3c5caf4 (main) Initial commit

首先,清理

I made a commit on invalid branch A, which was supposed to be made on branch B

以下操作将清理当前情况:

$ git switch a
$ git revert HEAD # Revert the mistake
[a 92f9287] Revert "Should be on b, but not a"

此时 'Should be on b, but not a' 的影响在 a 上被否定并且在 b 上不存在。

二、建立共同历史

避免 merge 问题就是建立一个共同的提交历史 - 在这里,这意味着挑选有问题的提交到 b 还原它:

$ git switch b
$ git cherry-pick 9eb80d9 # Reapply the mistake
$ git revert HEAD # AND revert it

结果是:

$ git log --all --decorate --oneline --graph
* 8d7c582 (b) Revert "Should be on b, but not a"   # Fixing Mistake
* ecf8f7c Should be on b, but not a                # Fixing Mistake
* 9eb80d9 Some change added to b only
| * 3339ef1 (a) Revert "Should be on b, but not a" # Clean up
| * c297cb5 Should be on b, but not a                
|/
* 3c5caf4 (main) Initial commit

此时'Should be on b, but not a'的影响在两个分支中都被否定了。

三、改对地方

所以我们有了一个干净的状态,现在所需要做的就是将提交重新应用到正确的分支:

$ git switch b
$ git revert HEAD

导致:

$ git log --all --decorate --oneline --graph
* fb744c1 (b) Revert "Revert "Should be on b, but not a"" # Re-apply
* 8d7c582 Revert "Should be on b, but not a"              # Fixing Mistake
* ecf8f7c Should be on b, but not a                       # Fixing Mistake
* 9eb80d9 Some change added to b only
| * 3339ef1 (a) Revert "Should be on b, but not a"        # Clean Up
| * c297cb5 Should be on b, but not a
|/
* 3c5caf4 (main) Initial commit

此时'Should be on b, but not a'的效果只在分支b上。

注意:重新应用更改的提交不一定是还原,同样可以是正常提交​​。

merge ,没问题

Branch B will be at some point merged to A

现在没问题了:

$ git switch a
$ git merge b
Merge made by the 'recursive' strategy.

使用所描述的提交/恢复将干净地应用导致:

$ git log --all --decorate --oneline --graph
*   bf1ff12 (a) Merge branch 'b' into a
|\
| * fb744c1 (b) Revert "Revert "Should be on b, but not a""
| * 8d7c582 Revert "Should be on b, but not a"
| * ecf8f7c Should be on b, but not a
| * 9eb80d9 Some change added to b only
* | 3339ef1 Revert "Should be on b, but not a"
* | c297cb5 Should be on b, but not a
|/
* 3c5caf4 (main) Initial commit

现在 'Should be on b, but not a' 的效果在分支 ab 上。

关于git - 恢复分支 A 上的提交,稍后将 merge 到 B。提交应该留在 B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69481571/

相关文章:

git - 从生产分支 merge 到主分支时如何在 Gitlab CI/CD 中增量版本或标记

git - 带有 $(GitVersion.NuGetVersion) 的标签源创建带有变量名称而非值的标签

git clone 通过 HTTPs 超时

git - 如何在 'git push' 中省略 <remote> 和 <ref> ?

git - 应用 git stash 时,我可以影响 "recursive"使用的 merge 策略吗?

Git 扩展——为什么我看到同一个分支有多个标签?

gitversion - 试图了解 GitVersion.yml 中的 "next-version"属性是如何工作的

git-http-后端

Git:在 gitattribute 中为整个文件夹指定 git merge 策略 "ours"(或者只是禁用特定文件夹的 merge 错误?)

git - .gitignore 和 "The following untracked working tree files would be overwritten by checkout"