如何撤消已完成的 “git commit --amend” 而不是“git commit”

我不小心修改了以前的提交。提交应该分开进行,以保留我对特定文件所做更改的历史记录。

有什么方法可以撤消上一次提交?如果我执行git reset --hard HEAD^ ,则第一次提交也将被撤消。

(我尚未推送到任何远程目录)

答案

您需要做的是创建一个与当前HEAD提交具有相同详细信息的新提交,但将父级作为HEAD的先前版本。 git reset --soft将移动分支指针,以便下一次提交发生在与当前分支头所在位置不同的提交之上。

# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit.
# HEAD@{1} gives you "the commit that HEAD pointed at before 
# it was moved to where it currently points at". Note that this is
# different from HEAD~1, which gives you "the commit that is the
# parent node of the commit that HEAD is currently pointing to."
git reset --soft HEAD@{1}

# commit the current tree using the commit details of the previous
# HEAD commit. (Note that HEAD@{1} is pointing somewhere different from the
# previous command. It's now pointing at the erroneously amended commit.)
git commit -C HEAD@{1}

使用ref-log

git branch fixing-things HEAD@{1}
git reset fixing-things

然后,您应该只在工作副本中拥有所有先前修改的更改,然后可以再次提交

查看以前的索引的完整列表,请键入git reflog

通过以下方式查找修改后的提交:

git log --reflog

注意:为了清楚起见,您可以添加--patch以查看提交的正文。与git reflog相同。

然后通过以下方法将 HEAD 重置为以前的任何提交:

git reset SHA1 --hard

注意: SHA1 替换为实际的提交哈希。另请注意,此命令将丢失所有未提交的更改,因此您可以将它们存放在前面。或者, 改用--soft保留最新更改 ,然后提交。

然后在它上面挑选另一个提交:

git cherry-pick SHA1

您可以随时拆分提交,请参见手册

  • 使用 git rebase -i commit ^ 启动交互式 rebase,其中 commit 是要拆分的提交。实际上,任何提交范围都可以,只要它包含该提交即可。
  • 用操作 “edit” 标记要拆分的提交。
  • 在编辑提交时,执行 git reset HEAD ^。结果是 HEAD 倒退了一个,索引也随之变化。但是,工作树保持不变。
  • 现在,将更改添加到您希望在第一次提交中拥有的索引。您可以使用 git add(可能是交互方式)或 git-gui(或两者都使用)来做到这一点。
  • 使用现在合适的提交消息来提交当前索引。
  • 重复最后两个步骤,直到工作树干净为止。
  • 使用 git rebase --continue 继续进行重新设置。

可能值得注意的是,如果您仍然在编辑器中看到 commit 消息,则可以删除该提交消息,它将中止git commit --amend命令。

也许可以使用git reflog在修改之前和修改之后获取两次提交。

然后使用git diff before_commit_id after_commit_id > d.diff来获取修改前后的差异。

接下来使用git checkout before_commit_id返回到提交之前

最后使用git apply d.diff来应用您所做的实际更改。

那解决了我的问题。

如果您已将提交推送到远程,然后错误地修改了该提交的更改,则可以解决您的问题。发出git log以在提交之前找到 SHA。 (这假设远程被命名为 origin)。现在,使用该 SHA 发出这些命令。

git reset --soft <SHA BEFORE THE AMMEND>
#you now see all the changes in the commit and the amend undone

#save ALL the changes to the stash
git stash

git pull origin <your-branch> --ff-only
#if you issue git log you can see that you have the commit you didn't want to amend

git stash pop
#git status reveals only the changes you incorrectly amended

#now you can create your new unamended commit

您可以在下面执行以撤消git commit —amend

  1. git reset --soft HEAD^
  2. git checkout files_from_old_commit_on_branch
  3. git pull origin your_branch_name

===================================

现在,您所做的更改与之前相同。这样您就完成了git commit —amend撤消— git commit —amend

现在,您可以执行git push origin <your_branch_name> ,以推送到分支。

距此晚了将近 9 年,但没有看到这种变化提到完成相同的事情(这是其中一些的组合,类似于最佳答案( https://stackoverflow.com/a/1459264/4642530 ) 。

搜索分支上所有分离的头

git reflog show origin/BRANCH_NAME --date=relative

然后找到 SHA1 哈希

重置为旧的 SHA1

git reset --hard SHA1

然后将其向上推。

git push origin BRANCH_NAME

做完了

这将使您完全恢复到旧的提交。

(包括先前覆盖的分离提交头的日期)

  1. 上次提交检出到临时分支

    git branch temp HEAD@{1}

  2. 重置上一次提交

    git reset temp

  3. 现在,您将拥有提交和先前提交的所有文件。检查所有文件的状态。

    git status

  4. 从 git 阶段重置您的提交文件。

    git reset myfile1.js (依此类推)

  5. 重新附加此提交

    git commit -C HEAD@{1}

  6. 添加文件并将其提交到新提交。