推送后还原合并

Bij*_*dra 62 git git-revert

我执行的步骤:

我有两个分支branch1和branch2,

$git branch --Initial state
$branch1

$git checkout branch2
$git pull origin branch1 --Step1
Run Code Online (Sandbox Code Playgroud)

我解决了冲突并做了一个

$git commit -m "Merge resolved"
Run Code Online (Sandbox Code Playgroud)

然后

$git checkout branch1
$git merge branch2
$git push origin branch1
Run Code Online (Sandbox Code Playgroud)

现在我意识到,在第1步,自动合并删除了一些代码,并且更改代码被推送,现在我想回到我的初始状态,以便还原任何更改.寻找一些直接的帮助?

ale*_*oot 74

您可以在官方指南之后恢复合并,但是这会让Git错误地认为合并的提交仍然在目标分支上.

基本上你必须:

git revert -m 1 (Commit id of the merge commit)
Run Code Online (Sandbox Code Playgroud)

  • 人们应该小心`1`.它意味着合并提交的"第一个"父级.但如果一个(假设)'偶然'将master合并到分支,那么快速转发master到合并提交 - 应该使用`-m 2`来恢复master上的合并. (21认同)
  • 小心那个“1”。它通过部分恢复合并搞乱了我的存储库,而我想完全恢复合并。我最终恢复了恢复! (2认同)

Ily*_*nov 21

尝试使用git reflog <branch>以找出合并之前分支的位置并git reset --hard <commit number>恢复旧版本.

Reflog将显示分支的旧状态,因此您可以将其返回到您喜欢的任何更改集.

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

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

  • 我已将代码推送到远程分支,这将如何从那里恢复代码.. (2认同)
  • 如果你已经推动了,你不想像Ilya所描述的那样重写当地历史 (2认同)
  • 对不起,我错过了那个...有时候你可以用git push -f重写远程历史记录.这取决于您的远程存储库配置和其他团队成员(如果他们不会因为强制推送而杀死您). (2认同)

Asa*_*aya 14

第一个选项是使用git revert.

git revert -m 1 [sha-commit-before-merge]
Run Code Online (Sandbox Code Playgroud)

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

git reset --hard [sha-commit-before-merge]
git push [origin] [branch] --force
Run Code Online (Sandbox Code Playgroud)

  • 使用第二种方法,效果非常好。这也让我的 GitHub 合并 PR 变得像以前一样干净。谢谢。 (7认同)

Aks*_*ran 7

git revert -m 1 <merge commit id>通过图形表示和示例逐步对给定答案进行更多解释。

\n

恢复合并提交并不像使用 那样简单git revert <commit-hash>,因为在从合并提交回看时,由于其两个父提交,Git 会感到困惑。要指定所需的父级,请使用该-m标志。由于 git 无法自动确定哪个父级是主线,哪个是要自动取消合并的分支,所以必须指定这一点。

\n

git 提交图

\n

iss53分支被合并到master,创建了Merge Commit, C6C6有两个父母,C5并且C4.

\n

需要将C6存储库恢复到其在 的状态C4。因此它必须指定哪个父级用于恢复命令。

\n
    \n
  • 为此,请检查git log此处代表实际提交哈希,其中包含图中的代码名称

    \n
    > git log\n\ncommit C6\nMerge: C4 C5\nAuthor: Mozz <mozz@example.com>\nDate:   Wed Feb 29 23:59:59 2020 +0100\n\nMerge branch \'iss53\' to master\n...\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
  • git log输出中,记下 附带的父 ID Merge: - -。其格式为Merge: parent1 parent2,此处Merge: C4 C5

    \n
  • \n
  • 提交C4位于master分支中,我们需要恢复到该分支,即父分支 1,并且-m 1此处需要(用于git log C4验证之前的提交以确认父分支)。

    \n
  • \n
  • 切换到进行合并的分支(这是这里的分支,我们的目标是从中master删除该分支)iss53

    \n

    执行 git revert with -m 1flag。

    \n
    # To revert to C4 in master branch\ngit revert C6 -m 1\n\n# C6 - is the merge commit hash\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
\n

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

\n
# revert to C5 in iss53 branch\ngit revert C6 -m 2\n\n# General\ngit revert <merge commit id> -m 1 (reverts to parent1)\ngit revert <merge commit id> -m 2 (reverts to parent2)\n# remember to check and verify the parent1 and parent2 with git log command.\n
Run Code Online (Sandbox Code Playgroud)\n

实际例子

\n

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

\n

之前的 git 树

\n

(对于提交的图形视图,请\xe2\x80\x94graphgit log [ SO ans ref ] 或这个更具交互性的 VS 代码扩展 - git graph一起使用)

\n

现在,我添加了一些新文件,修改了现有文件,并在每个分支上创建了单独的提交,然后将它们推送到原点。该图现在看起来像这样:

\n

提交后的 git 树

\n

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

\n

合并后的git树

\n

我想撤消合并提交并返回到分支中的最后一次提交main- 这是12a7327

\n

请注意,合并提交 -2ec06d9现在有两个父级 - 12a7327(in main) 和15bde47(in revert-test),git log现在检查,

\n
> git log\n\ncommit 2ec06d9d315a3f7919ffe4ad2c2d7cec8c8f9aa3 (HEAD -> main, origin/main, origin/HEAD)\nMerge: 12a7327 15bde47\nAuthor: Akshay <63786863+akshay@users.noreply.github.com>\nDate:   Sun Feb 5 00:41:13 2023 +0530\n\n    Merge pull request #1 from Akshay/revert-test\n    \n    Revert test\n
Run Code Online (Sandbox Code Playgroud)\n

要恢复合并提交并返回12a7327需要执行的操作,

\n
# To the First parent\ngit revert 2ec06d9 -m 1\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

git 恢复提交验证消息

\n

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

\n

恢复提交

\n

最后推送更改,现在合并提交更改消失了,日志将如下所示,

\n

最终的git树

\n