如何在不丢失更改的情况下取消提交上次未推送的git提交

有没有办法恢复提交,以便我的本地副本保持在该提交中所做的更改,但它们在我的工作副本中成为未提交的更改?回滚提交会将您带到上一个提交-我想保留所做的更改,但我将它们提交到错误的分支。

这没有被推动,只有承诺。

454394 次浏览

有很多方法可以做到这一点,例如:

如果你已经不是公开推送了提交:

git reset HEAD~1 --soft

就是这样,您的提交更改将在您的工作目录中,而LAST提交将从您的当前分支中删除。请参阅git重置人


如果你确实公开推送(在一个名为'master'的分支上):

git checkout -b MyCommit //save your commit in a separate branch just in case (so you don't have to dig it from reflog in case you screw up :) )

恢复正常提交并推送

git checkout mastergit revert a8172f36 #hash of the commit you want to destroy# this introduces a new commit (say, it's hash is 86b48ba) which removes changes, introduced in the commit in question (but those changes are still visible in the history)git push origin master

现在,如果您想在工作副本中进行本地更改时进行这些更改(“以便您的本地副本保留该提交中所做的更改”)-只需使用--no-commit选项恢复恢复提交:

git revert --no-commit 86b48ba (hash of the revert commit).

我制作了一个小例子:https://github.com/Isantipov/git-revert/commits/master

如果您推送了更改,您可以undo它并将文件移回阶段,而无需使用另一个分支。

git show HEAD > patchgit revert HEADgit apply patch

它将创建一个包含最后一个分支更改的补丁文件。然后它恢复更改。最后,将补丁文件应用于工作树。

对于这种情况:“这没有被推送,只承诺。”-如果您使用IntelliJ(或其他JetBrains IDE)和你还没做出改变,您可以执行下一步操作。

  1. 转到版本控制窗口(Alt+9/Command+9)-“日志”选项卡。
  2. 右键单击上一次提交之前的提交。
  3. 重置当前分支到这里
  4. 选择(!!!)
  5. 按下对话框窗口底部的重置按钮。

成交

这将“取消提交”您的更改并将您的git状态返回到上次本地提交之前的位置。您不会丢失您所做的任何更改。

对我来说,当我将更改推送到错误的分支并稍后意识到时,它就会发生。

git revert commit-hashgit push
git checkout my-other-branchgit revert revert-commit-hashgit push
  1. 恢复提交
  2. (创建并)检出其他分支
  3. 恢复

请确保在单独的文件夹中运行这些逗号之前备份您的更改

git签出branch_name

在你的分行结帐

git合并失败

中止合并

git状态

中止合并后检查代码的状态

git重置-硬源/branch_name

这些命令将重置您的更改并将您的代码与branch_name(分支)代码对齐。

2020简单方法:

git reset <commit_hash>

提交你想要保留的最后一次提交的哈希值。

添加我遵循的步骤,希望它对像我这样的初学者有帮助。

下面的图片显示了我已经推送到比特桶中的远程分支一个的提交。输入图片描述

从这5个提交中,我想保留最后2个,但前3个提交我希望它们被推到另一个分支“B”。

以下是我遵循的步骤:

在分支'A'内部:

  1. git revert <commit-hash>代表3次提交中的每一次。例如,d4a3734是图片中最后一次提交的提交哈希。(如果需要,您可以一次恢复多个提交-请参阅如何恢复多个git提交?
  2. git push

推送后,它看起来是这样的:-

输入图片描述

现在,我的分支一个中只有前2个提交,这就是我想要的。接下来,签出到想要的分支。如果它是一个新分支,请使用git checkout -b <branchname>。在我的例子中,我做了git checkout B

在分支'B'内部:

我只是选择了我想分支'B'的提交。在我的例子中,我做了:

git cherry-pick <commit-hash>

对于我恢复的这3个提交。

(同样,作为示例,git cherry-pick d4a3734其中d4a3734是图片中最后一次提交的提交哈希)

从2021年起为Google同事提供的新更新。

如果您是VSCode用户,这是一种撤消上次提交的现代方法。

  1. 转到左侧的源代码控制选项卡(快捷方式:Ctrl + Shift + G G)。
  2. 在盘旋更新图标左侧按...。参考下面的屏幕截图:源代码控制截图
  3. 导航到提交,然后到撤消上次提交。这是一个屏幕截图:输入图片描述

它所做的只是恢复您的存储库,就像您提交之前一样,您的更改未受影响。

撤消最后一次Git提交的最简单方法是使用以下选项之一执行git reset命令

  • 混合

假设你已经添加了两次提交并且你想撤消最后一次提交

$ git log --oneline
45e6e13 (HEAD -> master) Second commiteb14168 Initial commit

–soft选项撤消最后一次提交并保留对文件所做的更改

$ git reset --soft HEAD~1

$ git status
On branch masterChanges to be committed:(use "git restore --staged <file>..." to unstage)modified:   file.html

$ git log --oneline
eb14168 (HEAD -> master) Initial commit

–hard选项撤消最后一次提交并丢弃工作目录和索引中的所有更改

$ git reset --hard HEAD~1

$ git status
nothing to commit, working tree clean

$ git log --oneline
eb14168 (HEAD -> master) Initial commit

--mixed选项撤消最后一次提交并将更改保留在工作目录中,但不保留在索引中

$ git reset --mixed HEAD~1

$ git status
On branch masterChanges not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified:   file.html
no changes added to commit (use "git add" and/or "git commit -a")

$ git log --oneline
eb14168 (HEAD -> master) Initial commit