前言
这个教程基于我的个人理解和实践,所以请大家多多指教。错误之处,欢迎评论指出,方便大家也能参考.有时间的话我也很乐意及时的进行改正。如果教程中有表述不清楚的地方,也请指出,或提供建议。
在Git操作中,针对不同阶段的回退和还原操作有如下细分:
工作区:未add
举例 :针对代码文件进行了修改,但是还没有add的时候,这个时候如果后悔了,想恢复到修改之前的状态,按照我以前的操作可能就是一顿ctrl+z进行撤回,但是吧,如果修改的内容不多,还好,几秒就完事儿,但是如果修改的文件多,就可以使用另外的方式。
解决 :若要撤销对文件的修改并恢复到上一次提交的状态,在执行git add之前,可以使用命令git checkout -- <file>
或者命令git restore <file>
(不带--staged
参数)。这将丢弃工作区中的所有未暂存更改。
bash
$ 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>
。此命令会从暂存区移除指定文件的更改,让其返回至工作区,保留修改但不再处于暂存状态。
bash
$ 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指针移动到前一个提交,并将更改保留在工作区和暂存区。
bash
$ 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>
。请谨慎使用此命令,因为它会永久删除未提交的改动。
bash
$ git log
commit 52a9699a8eb50940d59bb54cbacd036f412aa261 (HEAD -> master)
Author: 郝乾维 <haoqw@primeton.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>
,它会产生一个新的反向补丁提交。
bash
$ git log
commit f020061fb81e14b555cb79d71eaa0e1291c748aa (HEAD -> master)
Author: user1 <user1@primeton.com>
Date: Thu Feb 1 17:29:43 2024 +0800
three
commit 52a9699a8eb50940d59bb54cbacd036f412aa261
Author: 郝乾维 <haoqw@primeton.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
参数时,仅影响暂存区,将已暂存的文件变更恢复至工作区版本,但不会影响当前工作目录下的文件内容。
- 不带stage参数时,作用类似于
总之,在进行任何Git回退操作时,请务必审慎对待,确保了解每个操作的潜在影响,尤其是在多人协作和已经推送了代码的情况下。