首页 文章

如何撤消Git中最近提交的提交?

提问于
浏览
18633

我不小心将错误的文件提交到Git,但我还没有将提交推送到服务器 .

如何从本地存储库中撤消这些提交?

30 回答

  • 372

    “将工作树重置为上次提交”

    git reset --hard HEAD^
    

    “从工作树中清除未知文件”

    git clean
    

    见 - Git Quick Reference

    NOTE: 此命令将删除您之前的提交,因此请谨慎使用! git reset --hard 更安全 -

  • 410

    单个命令:

    git reset --soft 'HEAD^'
    

    它可以很好地撤消上一次本地提交!

  • 443

    在我的情况下,我不小心提交了一些我不想要的文件 . 所以我做了以下工作:

    git reset --soft HEAD^
    git rm --cached [files you do not need]
    git add [files you need]
    git commit -c ORIG_HEAD
    

    使用gitk或git log --stat验证结果

  • 135

    对于本地提交

    git reset --soft HEAD~1
    

    或者如果你不记得它究竟在哪个提交中,你可以使用

    git rm --cached <file>
    

    对于推送提交

    从存储库历史记录中删除文件的正确方法是使用 git filter-branch . 那是,

    git filter-branch --index-filter 'git rm --cached <file>' HEAD
    

    但我建议您小心使用此命令 . 阅读更多git-filter-branch(1) Manual Page .

  • 127
    git rm yourfiles/*.class
    git commit -a -m "deleted all class files in folder 'yourfiles'"
    

    要么

    git reset --hard HEAD~1
    

    Warning: The above command will permanently remove the modifications to the .java files (and any other files) that you wanted to commit.

    hard resetHEAD-1 会在您错误提交之前将您的工作副本设置为提交状态 .

  • 299

    有很多方法可以做到:

    Git命令撤消上次提交/先前提交:

    Warning: 如果你不知道自己在做什么,请不要使用--hard . - 硬也是 dangerous ,它可能 delete your files.

    Basic command to revert the commit in Git is:

    $ git reset --hard <COMMIT -ID>
    

    要么

    $ git reset --hard HEAD~<n>
    

    COMMIT-ID :提交的ID

    n: 是您要还原的最后提交数

    您可以获得提交ID,如下所示:

    $ **git log --oneline**
    
    d81d3f1 function to subtract two numbers
    
    be20eb8 function to add two numbers
    
    bedgfgg function to mulitply two numbers
    

    其中 d81d3f1be20eb8 是提交ID .

    Now let's see some cases:

    假设您要还原最后一次提交'd81d3f1' . 这有两个选择:

    $ git reset --hard d81d3f1
    

    要么

    $ git reset --hard HEAD~1
    

    假设您要还原提交'be20eb8':

    $ git reset --hard be20eb8
    

    有关更多详细信息,您可以参考并尝试其他一些命令,以便将头重置为指定状态:

    $ git reset --help
    
  • 253

    使用reflog查找正确的状态

    git reflog
    

    reflog before
    重置前的REFLOG

    选择正确的reflog(在我的例子中为f3cb6e2)并输入

    git reset --hard f3cb6e2
    

    之后,repo HEAD将重置为HEADid
    reset effect
    LOGET RESET

    最后,reflog如下图所示

    reflog after
    REFLOG FINAL

  • 124

    添加/删除文件以获得您想要的方式:

    git rm classdir
    git add sourcedir
    

    然后修改提交:

    git commit --amend
    

    之前的错误提交将被编辑以反映新的索引状态 - 换句话说,它就像你从来没有犯过错误 .

    请注意,只有在尚未推送的情况下才应执行此操作 . 如果你已推,那么你只需要正常提交修复 .

  • 112

    如果您计划完全撤消本地提交,无论您在提交时做了什么更改,如果您对此没有任何担心,只需执行以下命令即可 .

    git reset --hard HEAD^1
    

    (此命令将忽略您的整个提交,您的更改将完全从本地工作树中丢失) . 如果要撤消提交,但希望在暂存区域中进行更改(在提交之前,就像在 git add 之后),请执行以下命令 .

    git reset --soft HEAD^1
    

    现在,您提交的文件将进入暂存区域 . 假设您想要更新文件,因为您需要编辑一些错误的内容,请执行以下命令

    git reset HEAD
    

    现在提交的文件从分段区域进入未分区区域 . 现在文件已经可以编辑了,所以无论你做什么改变,你都要编辑并添加它并进行新的/新的提交 .

    More

  • 165

    如果你不知道如何工作,撤销提交有点可怕 . 但是如果你理解的话,这实际上非常容易 .

    假设你有这个,其中C是你的HEAD,(F)是你文件的状态 .

    (F)
    A-B-C
        ↑
      master
    

    你想 nuke commit C and never see it again . 你做这个:

    git reset --hard HEAD~1
    

    结果是:

    (F)
    A-B
      ↑
    master
    

    现在B是HEAD . 因为您使用了 --hard ,所以您的文件将重置为它们在提交B时的状态 .

    啊,但是假设提交C不是灾难,但只是有点偏 . 在进行更好的提交之前,您希望 undo the commit but keep your changes 进行一些编辑 . 从这里开始,用C作为你的HEAD:

    (F)
    A-B-C
        ↑
      master
    

    你可以这样做,不用 --hard

    git reset HEAD~1
    

    在这种情况下,结果是:

    (F)
    A-B-C
      ↑
    master
    

    在这两种情况下,HEAD只是指向最新提交的指针 . 当你执行 git reset HEAD~1 时,你告诉Git将HEAD指针移回一次提交 . 但是(除非你使用 --hard )你保留文件原样 . 所以现在 git status 显示你已经检查过C的变化 . 你没有丢失任何东西!

    对于最轻的触摸,你甚至可以 undo your commit but leave your files and your index

    git reset --soft HEAD~1
    

    这不仅会使您的文件单独存在,甚至会使您的索引单独存在 . 当您执行 git status 时,您将看到索引中的文件与之前一样 . 事实上,在这个命令之后,你可以做 git commit 并且你将重做你刚才所做的相同提交 .

    还有一件事: Suppose you destroy a commit ,如第一个例子, but then discover you needed it after all ?运气好,对吗?

    不,还有办法让它回来 . 键入 git reflog ,您将看到已经移动的(部分)提交shas(即哈希)列表 . 找到您销毁的提交,并执行以下操作:

    git checkout -b someNewBranchName shaYouDestroyed
    

    你现在已经复活了这个提交 . 提交实际上并没有在Git中被摧毁大约90天,所以你通常可以回去救你并不意味着摆脱 .

  • 149

    How to undo the last Git commit?

    要将所有内容恢复到上次提交之前的状态,我们需要在HEAD之前重置为提交 .

    • 如果您不想保留所做的更改:
    git reset --hard HEAD^
    
    • 如果您想保留更改:
    git reset --soft HEAD^
    

    现在检查你的git日志 . 它将显示我们的上一次提交已被删除 .

  • 170

    撤消提交和重做

    $ git commit -m "Something terribly misguided"             # (1)
    $ git reset HEAD~                                          # (2)
    << edit files as necessary >>                              # (3)
    $ git add ...                                              # (4)
    $ git commit -c ORIG_HEAD                                  # (5)
    
    • 这是您要撤消的内容

    • 这会使您的工作树(磁盘上文件的状态)保持不变但撤消提交并保留您未提交的更改(因此它们将在 git status 中显示为"Changes not staged for commit",并且您需要在提交之前再次添加它们) . 如果您只想对上一次提交添加更多更改,或者更改提交消息1,则可以使用 git reset --soft HEAD~ ,这类似于 git reset HEAD~ (其中 HEAD~HEAD~1 相同),但会暂时保留现有更改 .

    • 对工作树文件进行更正 .

    • git add 要包含在新提交中的任何内容 .

    • 提交更改,重用旧的提交消息 . reset 将旧头复制到 .git/ORIG_HEAD ; commit-c ORIG_HEAD 将打开一个编辑器,该编辑器最初包含旧提交的日志消息,并允许您编辑它 . 如果您不需要编辑消息,则可以使用 -C 选项 .

    但请注意,如果您已对索引添加了任何新更改,则使用 commit --amend 会将它们添加到您之前的提交中 .

    如果代码已经推送到您的服务器并且您有权覆盖历史记录(rebase),那么:

    git push origin master --force
    

    你也可以看看这个答案:

    How to move HEAD back to a previous location? (Detached head)

    上面的答案将显示 git reflog ,用于找出您希望恢复的SHA-1是什么 . 一旦找到要撤消的点,就可以使用上面解释的命令序列 .


    1但是,请注意,如果您在提交消息中犯了错误,则无需重置为先前的提交 . 更简单的选择是 git reset (为了更新您之后所做的任何更改),然后是git commit --amend,这将打开预先填充了最后一次提交消息的默认提交消息编辑器 .

  • 100

    主要有两种情况

    You haven't pushed the commit yet

    如果问题是您提交的额外文件(并且您不希望存储库中存在这些文件),则可以使用 git rm 删除它们,然后使用 --amend 进行提交

    git rm <pathToFile>
    

    您还可以使用 -r 删除整个目录,甚至可以与其他Bash命令结合使用

    git rm -r <pathToDirectory>
    git rm $(find -name '*.class')
    

    删除文件后,您可以使用 --amend 选项进行提交

    git commit --amend -C HEAD # the -C option is to use the same commit message
    

    这将重写您最近的本地提交删除额外的文件,因此,这些文件永远不会在推送时发送,也将被GC从本地.git存储库中删除 .

    You already pushed the commit

    您可以应用其他方案的相同解决方案,然后使用 -f 选项执行 git push ,但它是 not recommended ,因为它会以不同的更改覆盖远程历史记录(它可能会弄乱您的存储库) .

    相反,你必须在没有 --amend 的情况下进行提交(记住这个关于-amend`:该选项重写最后一次提交的历史记录) .

  • 239

    我花了一段时间才弄明白,所以也许这会帮助别人......

    根据您是否已将提交公开(推送到远程存储库),有两种方法可以“撤消”上次提交:

    如何撤消本地提交

    假设我在本地提交,但现在想删除该提交 .

    git log
        commit 101: bad commit    # latest commit, this would be called 'HEAD'
        commit 100: good commit   # second to last commit, this is the one we want
    

    要将所有内容恢复到上次提交之前的方式,我们需要 resetHEAD 之前的提交:

    git reset --soft HEAD^     # use --soft if you want to keep your changes
    git reset --hard HEAD^     # use --hard if you don't care about keeping the changes you made
    

    现在 git log 将显示我们的上一次提交已被删除 .

    如何撤消公共提交

    如果您已将提交公开,则需要创建一个新的提交,它将“还原”您在先前提交(当前HEAD)中所做的更改 .

    git revert HEAD
    

    您的更改现在将被还原并准备好您提交:

    git commit -m 'restoring the file I removed by accident'
    git log
        commit 102: restoring the file I removed by accident
        commit 101: removing a file we don't need
        commit 100: adding a file that we need
    

    欲了解更多信息,请查看Git Basics - Undoing Things