分布式版本控制系统 Git | 四

分布式版本控制系统 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: 大梦三千秋 
Date:   Wed Feb 5 17:07:24 2020 +0800

    Use option --amend

commit 102a4a4f950cffae0acfb53a634012182fb8e8a1
Merge: d4a2555 0470264
Author: 大梦三千秋 
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 ..." 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: 大梦三千秋 
Date:   Wed Feb 5 18:31:19 2020 +0800

    initial commit

commit ddcba794e7a6b4bed818425b16b6a40a6565a975
Author: 大梦三千秋 
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 ..." to unstage)
        modified:   about_git.txt
        renamed:    readme.txt -> readme.md

这里会发现 Changes to be committed 文字下方,提示使用 git reset HEAD ... 来取消暂存。现在尝试使用该命令进行取消暂存操作:

$ 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 ..." to unstage)
        renamed:    readme.txt -> readme.md

Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)
        modified:   about_git.txt

现在,使用 git status 可以看到,about_git.txt 已经是修改未暂存的状态。

这就是 git reset 命令目前需要了解且能够达到的效果。至于关于 reset 更多的细节以及它能够完成其他什么效果,可以查看下面的链接,进一步了解:

https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified

撤销对文件的修改

假设现在不想保留对 about_git.txt 的修改?假如想回退到上次提交的版本(或者刚克隆下来的版本等等),git status 的命令同样也提示了使用哪个命令能够达到这样的效果。

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD ..." to unstage)
        renamed:    readme.txt -> readme.md

Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)
        modified:   about_git.txt

这里我们按照提示,使用 git checkout -- 来实现这个需求:

$ git checkout -- about_git.txt

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD ..." to unstage)
        renamed:    readme.txt -> readme.md

这里可以看到,再次使用 git status 能够发现对于 about_git.txt 的修改已经被撤销,版本回退到未对 about_git.txt 进行修改的版本。

注意: git checkout -- 这个命令有风险。使用之前需要再三确认是否不需要这个文件。因为这个命令会使文件的任何修改都消失。

如果文件需要保留,但是仍然需要撤销,这里可以考虑 Git 分支,用以保存进度与分支。后续将会介绍 Git 分支

在 Git 中,已经提交的东西,一些误操作往往能够恢复。但是,未提交的东西,往往丢失后就无法再恢复了。所以要慎重使用撤销操作。


以上就是本篇的主要内容

未完待续

欢迎关注微信公众号《书所集录》

你可能感兴趣的:(python)