在日常开发的过程中,我们可能会遇到以下几种的场景:
场景一:
在工作区修改了文件内容,还没添加到暂存区,发现修改错了想要撤销修改。
$ cat hello.txt
hello Git
修改hello.txt 文件,添加一行内容hello world
$ vim hello.txt
hello Git
hello world
$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
使用git checkout --
撤销修改
$ git checkout -- hello.txt
查看状态
$ git status
On branch master
nothing to commit, working tree clean
查看hello.txt 文件内容
$ cat hello.txt
hello Git
hello.txt 文件回到和版本库一样。
场景二:
与场景一一样在工作区修改了文件内容,不同的是这个时候被修改的 hello.txt 文件已经添加到暂存区了,需要撤销修改。
$ vim hello.txt
hello Git
hello world
查看状态
$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
将修改的文件添加到暂存区
$ git add hello.txt
查看状态
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: hello.txt
现在我们首先将文件从暂存区回退到工作区
$ git reset HEAD hello.txt
Unstaged changes after reset:
M hello.txt
查看状态,此时和场景一的状态是一样的了。
$ git status
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: hello.txt
no changes added to commit (use "git add" and/or "git commit -a")
使用git checkout --
撤销修改
$ git checkout -- hello.txt
场景三:
与场景二一样在工作区修改了文件内容,被修改的 hello.txt 文件已经添加到暂存区了,这个时候在工作区又做了修改,需要撤销本次修改。
$ vim hello.txt
hello Git
hello world
将修改的文件添加到暂存区
$ git add hello.txt
再次编辑文件,添加新的一行内容hello Java
$ vim hello.txt
hello Git
hello world
hello Java
查看状态
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: hello.txt
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: hello.txt
此时,hello.txt 文件同时出现在暂存区和非暂存区。
我们想要撤销本次的修改,那么只要执行git checkout -- hello.txt
就可以了。
$ git checkout hello.txt
Updated 1 path from the index
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: hello.txt
查看文件内容,本次修改已经撤销了。
$ cat hello.txt
hello Git
hello world
如果hello.txt 修改后,还没有添加到暂存区,现在想要撤销,执行git checkout -- hello.txt
则回到和版本库一样的状态。
如果hello.txt 已经添加到暂存区,又做了修改,现在想要撤销本次修改,执行git checkout -- hello.txt
,撤销的是工作目录的修改,则回到和暂存区一样的状态。
当然如果是一个新的文件还没有添加到暂存区,也就没有Git撤销操作了。总之,就是让这个文件回到最近一次git commit或git add时的状态。
场景四:
这个时候终于把hello.txt 文件修改完了,愉快的执行了提交。
$ git commit -m "fix bug #666"
[master 50b27fc] fix bug #666
1 file changed, 1 insertion(+)
提交完后发现bug号写错了,其实修改的是bug #66,想要修改提交说明。
查看提交说明
$ git log
commit 50b27fce9b19dd25736893bcc3bb49c46a1242ae (HEAD -> master)
Author: geekymv
Date: Thu Jun 13 19:22:14 2019 +0800
fix bug #666
修改最近一次的提交说明
$ git commit --amend -m "fix bug #66"
[master 5c10da1] fix bug #66
Date: Thu Jun 13 19:22:14 2019 +0800
1 file changed, 1 insertion(+)
$ git log
commit 5c10da1d45b53cf2f98c538b9f8d758ff961fd81 (HEAD -> master)
Author: geekymv
Date: Thu Jun 13 19:22:14 2019 +0800
fix bug #66
已经成功修改了提交说明,并没有新增commit id。
$ git log
commit 5c10da1d45b53cf2f98c538b9f8d758ff961fd81 (HEAD -> master)
Author: geekymv
Date: Thu Jun 13 19:22:14 2019 +0800
fix bug #66
commit 29cf508b469fd4b89de66b8b979e14b10c2663ea
Author: geekymv
Date: Thu Jun 13 18:55:47 2019 +0800
修改文件
commit 0a49afaf82d809568ecc942baf4c170d5027ef6d
Author: geekymv
Date: Wed Jun 5 21:03:17 2019 +0800
add
git log 命令显示从最近到最远的提交说明,如果觉得输出的信息太多,可以加上参数--pretty=oneline
$ git log --pretty=oneline
5c10da1d45b53cf2f98c538b9f8d758ff961fd81 (HEAD -> master) fix bug #66
29cf508b469fd4b89de66b8b979e14b10c2663ea 修改文件
0a49afaf82d809568ecc942baf4c170d5027ef6d add
这下清爽多了不是!
在Git中,用HEAD表示当前版本,上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,
当然往上10个版本写10个^比较容易数不过来,所以写成HEAD~10。
$ git reset --hard HEAD^
HEAD is now at 29cf508 修改文件
$ git log --pretty=oneline
29cf508b469fd4b89de66b8b979e14b10c2663ea (HEAD -> master) 修改文件
0a49afaf82d809568ecc942baf4c170d5027ef6d add
可以看到当前版本是29cf50...
。
现在要想还回到5c10da1d45b53cf2f98c538b9f8d758ff961fd81
版本,
当然版本号没必要写全,前几位就可以了,Git会自动匹配。
$ git reset --hard 5c10da
HEAD is now at 5c10da1 fix bug #66
可以看到又回到了5c10da...
版本
$ git log --pretty=oneline
5c10da1d45b53cf2f98c538b9f8d758ff961fd81 (HEAD -> master) fix bug #66
29cf508b469fd4b89de66b8b979e14b10c2663ea 修改文件
0a49afaf82d809568ecc942baf4c170d5027ef6d add
当你用$ git reset --hard HEAD^
命令回退到29cf50...
版本时,再想恢复到最新版本怎么办呢?
上面我们能恢复是因为我们在笔记中记录了 commit id。这个时候使用git log
已经看不到最新版本到commit id 了。
不用担心,在Git中总是有后悔药可以吃,git reflog
记录你的每一次命令。此时我们就可以看到最新版本的 commit id 是5c10da1...
$ git reflog
29cf508 (HEAD -> master) HEAD@{0}: reset: moving to 29cf
5c10da1 HEAD@{1}: reset: moving to 5c10da1d45b53cf2f98c538b9f8d758ff961fd81
29cf508 (HEAD -> master) HEAD@{2}: reset: moving to HEAD^
5c10da1 HEAD@{3}: commit (amend): fix bug #66
50b27fc HEAD@{4}: commit: fix bug #666