如何完成撤销提交,以及如何撤销多个提交

26

我希望这很简单,但我在git-scm中找不到它。

我为一个公共项目做了很多小的提交,但我的所有工作都很糟糕。我想要删除我所做的所有事情。有些东西我只是本地提交的,有些则推送到了“origin master”。

第一次提交(一周前)是bdbad86...最近的一次是e82401b...

我想让它们全部消失。我尝试撤销其中一个。

git status  
# On branch master  
# You are currently reverting commit e82401b.  
#   (all conflicts fixed: run "git revert --continue")  
#   (use "git revert --abort" to cancel the revert operation)  
  1. 我无法弄清如何完成还原。
  2. 我不想分别执行每个提交,我想将它们全部删除。

git revert --abort 对我有用。 - Mark Kahn
3个回答

9

我假设在你的工作中没有其他人插入提交,并且你的错误提交在仓库历史记录中形成了一个连续的范围。否则,你需要更复杂的操作。让我们假设你的历史记录是这样的:

e82401b - (master, HEAD) My most recent private commit
...
bc2da37 - My first private commit
cf3a183 - (origin/master) My most recent bad public commit
...
292acf1 - My first bad public commit
82edb2a - The last good public commit

我们要做的第一件事是清除你还未公开的提交记录。你可以使用以下命令来执行此操作(请注意,你的更改将会被删除且不可恢复):
git reset --hard cf3a183 

同义 (更可读):

git reset--hard origin/master

现在你对仓库的视图与origin/master的视图一致了。你想要撤销你不好的公共更改,并将它们作为还原提交发布。以下是创建单个还原提交的说明。

你可以使用git revert --no-commit a..b来还原从提交a之后(注意!)到提交b,包括它们在内的所有提交记录。还原操作将被暂存以供你提交。因此,在这里,我们会执行如下命令:

git revert --no-commit 82edb2a..HEAD

或者等价地说:
git revert --no-commit 292acf1^..HEAD

记住,HEAD现在指向与origin/master相同的位置。

运行revert命令后,您现在已经将更改暂存并准备好提交,所以只需运行简单的git commit -m“撤销我不小心推送并公开的那些错误更改”即可。


谢谢,这是我需要的信息。还有一个问题:我如何获取(master,HEAD)或(origin/master)信息,以便我知道何时执行这两组命令? - Pat Farrell
1
@Pat 最简单的方法是设置一个替代形式的 git log,以便一目了然地获取这些信息。您可以在这里阅读有关要使用的格式的信息。一个很好的起点是像这样的东西:git log --pretty="%h %Cgreen%d%Creset %s %an %Cblue(%cr)" - Chris Hayes

8

不要运行

git revert --continue

而是运行

git commit -m "在这里填入提交信息"

如果这样还不行,请确保已暂存涉及到的所有文件进行还原,即使是那些您已经还原并且放弃更改的文件。


9
尽管我已经提交了所有更改,但我发现我仍然被卡在还原的状态中。我不得不运行命令 git commit -m "empty commit to escape revert" --allow-empty,但这似乎已经解决了问题。 - Ryan1729

1
这个问题已经得到正确回答,但我想解决操作者问题的第一个点——我不知道如何完成还原。如果像我一样被卡在还原状态中并且在这里寻找答案,请注意。如果您正在还原文件内的某些更改,则可以直接使用git revert --continue。但是,如果您卡在还原状态中,那么很可能是因为您试图还原创建文件的提交,并且该文件在任何后续提交中都已被修改。
以一个例子来说明:
1c40cd3 added fileB
4e06828 added fileA
faf29dd (origin/main, origin/HEAD, main) Merged in feature5 (pull request #13)
6e735e3 (origin/feature5, feature5) updated file.txt
fb51fca added file.txt
744ba74 Initial commit

现在,如果您尝试还原fb51fca(添加file.txt),它会显示类似于以下内容:

$ git revert fb51fca
CONFLICT (modify/delete): file.txt deleted in parent of fb51fca (added file.txt) and modified in HEAD.  Version HEAD of file.txt left in tree.
error: could not revert fb51fca... added file.txt
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".

$ git status
On branch feature6
You are currently reverting commit fb51fca.
  (fix conflicts and run "git revert --continue")
  (use "git revert --skip" to skip this patch)
  (use "git revert --abort" to cancel the revert operation)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add/rm <file>..." as appropriate to mark resolution)
        deleted by them: file.txt

您可以清楚地看到file.txt deleted in fb51fca (added file.txt) and modified in HEAD. Version HEAD of file.txt left in tree.。现在,您可以执行git add -Agit commit ...,但是

还原所做的是回到历史记录(在指定的提交中),删除该提交中所进行的更改,并创建一个新的提交。但问题是,您创建了一个文件,现在还原正在删除它。最终,没有文件可用于暂存,而且正如您所知,git不允许空目录或空提交。

但是有一种解决空提交的方法。就像Ryan建议的那样,您可以执行git commit -m "empty commit to escape revert" --allow-empty。Git Revert可能没有使用此--allow-empty标志,这可能是它无法进行提交并陷入还原状态的原因。

总之,如果您陷入还原状态,则可能正在尝试还原不合理的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接