likes
comments
collection
share

git之后悔药的几种食用方式

作者站长头像
站长
· 阅读数 2

前言

       这个教程基于我的个人理解和实践,所以请大家多多指教。错误之处,欢迎评论指出,方便大家也能参考.有时间的话我也很乐意及时的进行改正。如果教程中有表述不清楚的地方,也请指出,或提供建议。 在Git操作中,针对不同阶段的回退和还原操作有如下细分:

工作区:未add

       举例:针对代码文件进行了修改,但是还没有add的时候,这个时候如果后悔了,想恢复到修改之前的状态,按照我以前的操作可能就是一顿ctrl+z进行撤回,但是吧,如果修改的内容不多,还好,几秒就完事儿,但是如果修改的文件多,就可以使用另外的方式。

       解决:若要撤销对文件的修改并恢复到上一次提交的状态,在执行git add之前,可以使用命令git checkout -- <file>或者命令git restore <file>(不带--staged参数)。这将丢弃工作区中的所有未暂存更改。

$ git status
On branch master
Changes 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:   one.txt

no changes added to commit (use "git add" and/or "git commit -a")
------------------------------
$ git restore one.txt
------------------------------
$ git status
On branch master
nothing to commit, working tree clean
------------------------------

暂存区:(已add但未commit)

       举例:针对代码文件做了修改,并且也add了,但是这个时候如果后悔了,想恢复到修改之前的状态。此时不能使用上面的方式,但是我们仍然有办法。

       解决

  • 对于已添加(add)到暂存区但还未提交(commit)的改动,要撤回到工作区(未add)状态,如代码中提示可使用git restore --staged <file>。此命令会从暂存区移除指定文件的更改,让其返回至工作区,保留修改但不再处于暂存状态。
$ git add one.txt
------------------------------
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   one.txt
  • 若想继续将文件恢复至最后一次提交时的状态(即既取消暂存又撤销修改),可点击工作区回退方案参考。

本地仓库:(已commit但未push)

       举例:针对代码文件进行了修改,已经add且commit了,但是因为各种原因,不想把commit提交到远程仓库,就是不想push了,想撤回到修改之前。

       解决

  • 要撤销最近的一次提交但保留修改以便重新提交,可以使用git reset HEAD~1(或指定commit ID)。这会将HEAD指针移动到前一个提交,并将更改保留在工作区和暂存区。
$ git commit one.txt -m 'first commit'
[master 251478b] first commit
 1 file changed, 1 insertion(+)
------------------------------
$ git reset HEAD~1
Unstaged changes after reset:
M       one.txt
------------------------------
$ git status
On branch master
Changes 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:   one.txt

no changes added to commit (use "git add" and/or "git commit -a")
  • 若要完全回滚到某个提交且丢弃之后的所有更改(包括工作区和暂存区的),使用git reset --hard <commitID>。请谨慎使用此命令,因为它会永久删除未提交的改动。
$ git log
commit 52a9699a8eb50940d59bb54cbacd036f412aa261 (HEAD -> master)
Author: test <test@xxxx.com>
Date:   Thu Feb 1 17:23:51 2024 +0800

    second
......
......
......
------------------------------
$ git reset --hard 52a9699a8eb50940d59bb54cbacd036f412aa261
HEAD is now at 52a9699 second
------------------------------
$ git status
On branch master
nothing to commit, working tree clean
  • 若要创建一个新的提交来撤销先前提交的影响而不改变历史记录,使用git revert <commitID>,它会产生一个新的反向补丁提交。
$ git log
commit f020061fb81e14b555cb79d71eaa0e1291c748aa (HEAD -> master)
Author: user1 <user1@primeton.com>
Date:   Thu Feb 1 17:29:43 2024 +0800

    three

commit 52a9699a8eb50940d59bb54cbacd036f412aa261
Author: test <test@xxxx.com>
Date:   Thu Feb 1 17:23:51 2024 +0800

    second
......
......
......
------------------------------
$ git revert f020061fb81e14b555cb79d71eaa0e1291c748aa
[master 4e02426] Revert "three"
 1 file changed, 1 insertion(+), 2 deletions(-)
------------------------------
$ git status
On branch master
nothing to commit, working tree clean

远程仓库(慎之又慎):push之后

  • 回滚已推送的提交需要格外小心,因为这可能会影响其他协作者的工作流程。通常情况下,应当避免直接修改历史记录,而是通过创建新的revert提交来解决问题:
  • 使用git revert <commitID>生成一个新的反转提交,解决冲突后提交并推送到远程仓库:git push

关于git restore补充说明:

  • git restore命令可用于恢复文件的不同状态:

    • 不带stage参数时,作用类似于git checkout -- <file>,无论文件是否被add过,都会将其内容恢复到最近一次提交的状态,并清除任何未提交的修改。
    • --staged参数时,仅影响暂存区,将已暂存的文件变更恢复至工作区版本,但不会影响当前工作目录下的文件内容。

总之,在进行任何Git回退操作时,请务必审慎对待,确保了解每个操作的潜在影响,尤其是在多人协作和已经推送了代码的情况下。