分布式版本控制系统 Git | 四
Git 基础 | 撤销修改
在工作过程中,很有可能会遇到需要撤销某些操作的时候。Git 也提供这样的命令帮助撤销所做的修改。但是有一点需要注意,某些撤销操作是不可逆的。这也是为数不多可能因为操作失误导致工作进度丢失的操作。
工作过程中,可能会遇到下面的状况。完成修改提交之后,发现有文件未添加,或者提交信息错误。这里,可以使用 git commit
配合 --amend
选项的命令尝试重新提交:
$ git commit -m "Something different"
[master d888984] Something different
1 file changed, 1 insertion(+)
$ git status
On branch master
nothing to commit, working tree clean
$ git commit --amend
[master bc3e952] Use option --amend
Date: Wed Feb 5 17:07:24 2020 +0800
1 file changed, 1 insertion(+)
上面这个命令会将暂存区的文件提交。但如果上次提交文件未做任何修改,立刻使用命令,那么快照保持不变,会启动编辑器,这时修改里面的提交信息就会覆盖上次的提交的信息。
在上面使用的命令中,第一次使用 git commit
提交的信息是 Something different
。使用 git commit --amend
命令后,这里由于在提交后,没有进行更改,所以使用命令后直接打开编辑器修改了提交信息,更改为 Use option --amend
。
$ git log
commit ddcba794e7a6b4bed818425b16b6a40a6565a975 (HEAD -> master)
Author: 大梦三千秋 <yiluolion@gmail.com>
Date: Wed Feb 5 17:07:24 2020 +0800
Use option --amend
commit 102a4a4f950cffae0acfb53a634012182fb8e8a1
Merge: d4a2555 0470264
Author: 大梦三千秋 <yiluolion@gmail.com>
Date: Tue Feb 4 21:53:59 2020 +0800
Fix conflict
使用 git log
查看提交日志时,发现先提交的信息 Something different
并没有显示在提交日志中。
这就是上面提及的选项 --amend
的作用之一。未做修改时,使用搭配该选项的 git commit
命令,修改的只是提交信息。
使用该命令的还有另外一种情况。提交之后,发现未暂存某些需要的修改。例如:
$ git commit -m "initial commit"
[master 668ee3f] initial commit
1 file changed, 1 insertion(+)
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
forgotten_file
$ git add forgotten_file
$ git commit --amend
[master 34cec72] initial commit
Date: Wed Feb 5 18:31:19 2020 +0800
2 files changed, 2 insertions(+)
create mode 100644 forgotten_file
$ git status
On branch master
nothing to commit, working tree clean
$ git log
commit 34cec724a319c5797a834c0e4b698029c3ba5994 (HEAD -> master)
Author: 大梦三千秋 <yiluolion@gmail.com>
Date: Wed Feb 5 18:31:19 2020 +0800
initial commit
commit ddcba794e7a6b4bed818425b16b6a40a6565a975
Author: 大梦三千秋 <yiluolion@gmail.com>
Date: Wed Feb 5 17:07:24 2020 +0800
Use option --amend
上述 Git 命令中,提交之后,发现 forgotten_file
未暂存,使用命令暂存提交后,使用 git status
确认工作区干净,意味着遗漏的文件也重新放到暂存区,这个时候使用 git log
查看提交日志可以发现,只有一次提交,因为第二次提交代替第一次提交的结果。
取消暂存文件
假设模拟场景是这样的:工作中修改了两个文件,初衷是将两个文件作为独立的修改提交,但是却使用了 git add *
命令,将两个文件同时放入了暂存区。这时想将其中一个文件取消暂存?使用 git status
命令也能够得到提示:
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: about_git.txt
renamed: readme.txt -> readme.md
这里会发现 Changes to be committed
文字下方,提示使用 git reset HEAD <file> ...
来取消暂存。现在尝试使用该命令进行取消暂存操作:
$ git reset HEAD about_git.txt
Unstaged changes after reset:
M about_git.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: readme.txt -> readme.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: about_git.txt
现在,使用 git status
可以看到,about_git.txt
已经是修改未暂存的状态。
这就是 git reset
命令目前需要了解且能够达到的效果。至于关于 reset
更多的细节以及它能够完成其他什么效果,可以查看下面的链接,进一步了解:
撤销对文件的修改
假设现在不想保留对 about_git.txt
的修改?假如想回退到上次提交的版本(或者刚克隆下来的版本等等),git status
的命令同样也提示了使用哪个命令能够达到这样的效果。
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: readme.txt -> readme.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: about_git.txt
这里我们按照提示,使用 git checkout -- <file>
来实现这个需求:
$ git checkout -- about_git.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: readme.txt -> readme.md
这里可以看到,再次使用 git status
能够发现对于 about_git.txt
的修改已经被撤销,版本回退到未对 about_git.txt
进行修改的版本。
注意:
git checkout -- <file>
这个命令有风险。使用之前需要再三确认是否不需要这个文件。因为这个命令会使文件的任何修改都消失。
如果文件需要保留,但是仍然需要撤销,这里可以考虑 Git 分支,用以保存进度与分支。后续将会介绍 Git 分支
。
在 Git 中,已经提交的东西,一些误操作往往能够恢复。但是,未提交的东西,往往丢失后就无法再恢复了。所以要慎重使用撤销操作。
以上就是本篇的主要内容