git 推送后还原合并

yrwegjxp  于 2023-02-07  发布在  Git
关注(0)|答案(6)|浏览(184)

本人执行的步骤:
我有两个分支,分支1和分支2,

$git branch --Initial state
$branch1

$git checkout branch2
$git pull origin branch1 --Step1

我解决了冲突并做了

$git commit -m "Merge resolved"

那么

$git checkout branch1
$git merge branch2
$git push origin branch1

现在我意识到,在第一步,自动合并删除了一些代码,更改代码被推送。现在我想回到我的初始状态,以恢复任何更改。寻找一些即时的帮助?

snvhrwxg

snvhrwxg1#

您可以在official guide之后恢复合并,但这会让Git误以为合并后的提交仍然在目标分支上。
基本上,您必须:

git revert -m 1 (Commit id of the merge commit)
x3naxklr

x3naxklr2#

尝试使用git reflog <branch>查找合并前分支的位置,使用git reset --hard <commit number>恢复旧版本。
Reflog会显示分支的旧状态,所以你可以把它返回到任何你喜欢的变更集中。

使用git reset时,请确保您位于正确的分支中

要更改远程存储库历史记录,您可以执行git push -f,但不建议这样做,因为其他人可能已经下载了您推送的更改。

6ovsh4lw

6ovsh4lw3#

第一个选项是使用git revert

git revert -m 1 [sha-commit-before-merge]

git revert将恢复更改,但会保留历史记录。因此,您将无法继续在同一分支中工作,因为您无法再看到合并分支和特性分支之间的实际差异。使用以下方法也可以删除历史记录。当且仅当您是此时唯一将更改推送到分支的人时,请非常小心地执行此操作。

git reset --hard [sha-commit-before-merge]
git push [origin] [branch] --force
bweufnob

bweufnob4#

在我的例子中,我合并了我的分支(比如:my-branch)与另一个feature分支(feature-branch)而不是master的关系,所以我的分支历史是这样的:

my-branch (before merge)

---master----m1----m2----m3---m4

在将其与另一个在master上提交了f1, f2feature-branch合并后,它变成了这样:

my-branch (after merge)

---master----m1----m2----f1----f2----m3---m4----mergecommit

这可能是因为在我的分支上工作时,我在2次提交后从master进行了合并,或者2个分支中的一个可能没有与master保持最新。所以在这种情况下,git revert -m 1没有工作,因为它将f1f2提交留在中间。
这个解决方案很简单,在正常情况下也可以工作,我们没有中间提交:

git rebase -i HEAD~6

根据你想要修改的过去提交次数,使用合适的数字代替6。现在Vim编辑器打开了,只需将不需要的提交标记为drop和same,然后退出:wq验证日志:

git log --oneline

力推

git push -f

现在远程分支应该处于先前状态。

pw9qyyiw

pw9qyyiw5#

正如另一个答案中提到的,在合并时执行git revert的主要问题是git仍然认为所有先前的提交都被合并了(它只会改变代码)。如果你稍后尝试合并该分支,你会发现先前的提交都不见了。
更好的方法(显然是在和你的团队商量过之后,这样他们就不会一直在一个有问题的分支上工作)是git reset到一个更早的提交。它不一定是一个硬重置,因为它只处理如何处理你当前正在工作的修改,所以这部分取决于你。
如果你想在重置之前先在之前的提交上做修改,你也可以从之前的提交创建一个临时分支,在这种情况下,你会重置到临时分支上的提交。
如果不从上游进行拉取,就无法进行推送,但显然您不想拉取要恢复的更改,因此,您需要执行强制推送(或者如果在此期间推送了任何更改,则使用租约停止强制推送)。
边注:作为VS代码和Git Graph的爱好者,我发现强制推送很容易做到,只需右键单击本地分支标记名并选择'推送分支...',选择强制或强制租约,并选中设置上游框。

vecaoik1

vecaoik16#

通过图形表示和示例逐步详细说明给定答案git revert -m 1 <merge commit id>
恢复合并提交并不像git revert <commit-hash>那样简单,因为Git在返回合并提交时会因为它有两个父提交而感到困惑。要指定所需的父提交,请使用-m标志。由于git无法确定哪个父提交是主线,哪个父提交是要自动取消合并的分支,因此必须指定这一标志。

iss53分支被合并到master中,创建了Merge CommitC6C6有两个父分支,C5C4
需要恢复C6并将存储库返回到C4时的状态,因此必须指定revert命令使用哪个父存储库。

  • 为此,请检查git log,(* 此处表示实际提交哈希,代码名称来自图表 *)
> git log

commit C6
Merge: C4 C5
Author: Mozz <mozz@example.com>
Date:   Wed Feb 29 23:59:59 2020 +0100

Merge branch 'iss53' to master
...
  • git log输出中,记下Merge: - -附带的父ID。它的格式为Merge: parent1 parent2,此处为Merge: C4 C5
  • C4提交在master分支中,我们需要恢复到该分支,即父1,此处需要-m 1(使用git log C4验证之前的提交以确认父分支)。
  • 切换到进行合并的分支(这里是master分支,我们的目标是从中删除iss53分支)

使用-m 1标志进行git还原。

# To revert to C4 in master branch
git revert C6 -m 1

# C6 - is the merge commit hash

对于其他一些情况,如果需要,请恢复为C5

# revert to C5 in iss53 branch
git revert C6 -m 2

# General
git revert <merge commit id> -m 1 (reverts to parent1)
git revert <merge commit id> -m 2 (reverts to parent2)
# remember to check and verify the parent1 and parent2 with git log command.

示例

在一个只有main分支的现有项目上创建了一个新的分支revert-test,提交图现在看起来像这样。

  • (对于提交的图形视图,请将—graphgit log [SO ans ref]一起使用,或者使用更具交互性的VS代码扩展-git graph)*

现在,我已经添加了一些新文件,修改了现有文件,并在每个分支上创建了单独的提交,然后将它们推到原点。

然后,从GitHub创建一个拉取请求,并将revert-test分支合并到main

我想撤消合并提交并返回到main分支中的最后一次提交-即12a7327
注意合并提交-2ec06d9现在有两个父提交-12a7327(在main中)和15bde47(在revert-test中),现在检查git log

> git log

commit 2ec06d9d315a3f7919ffe4ad2c2d7cec8c8f9aa3 (HEAD -> main, origin/main, origin/HEAD)
Merge: 12a7327 15bde47
Author: Akshay <63786863+akshay@users.noreply.github.com>
Date:   Sun Feb 5 00:41:13 2023 +0530

    Merge pull request #1 from Akshay/revert-test
    
    Revert test

要还原合并提交并返回到12a7327,需要执行以下操作:

# To the First parent
git revert 2ec06d9 -m 1

现在一条提交消息将显示在编辑器中,其中指定了细节、检查和验证。

这样就创建了一个Revert提交,它执行合并提交的反向更改。

最后推送更改,现在合并提交更改消失,日志将看起来像,

相关问题