一、管理修改
为什么说Git管理的是修改,而不是文件呢?我们还是做实验。第一步,对readme.txt做一个修改,比如加一行内容:
Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes.
第二步,添加到暂存区:
➜ testcase git:(master) ✗ git add readme.txt ➜ testcase git:(master) ✗ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: readme.txt
第三步,再修改readme.txt:
Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes of files.
第四步,提交:
➜ testcase git:(master) ✗ git commit -m "git tracks changes" [master 170fed5] git tracks changes 1 file changed, 1 insertion(+)
第五步,查看状态:
➜ testcase git:(master) ✗ git status On branch master 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: readme.txt no changes added to commit (use "git add" and/or "git commit -a")
输出结果显示,第二次的修改没有被提交。
我们回顾一下操作过程:
第一次修改 -> git add
-> 第二次修改 -> git commit
Git管理的是修改,当你用git add
命令后,在工作区的第一次修改被放入暂存区,准备提交。但是,在工作区的第二次修改并没有放入暂存区,所以,git commit
只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
第六步,提交后,用git diff HEAD -- readme.txt
命令可以查看工作区和版本库里面最新版本的区别:
diff --git a/readme.txt b/readme.txt index 76d770f..a9c5755 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. -Git tracks changes. +Git tracks changes of files.
HEAD指向的是版本库中的当前版本,而file指的是当前工作区中的文件。
“+”代表工作区新增加的内容,“-”代表版本库新增加的内容。
可见,第二次修改确实没有被提交。
那怎么提交第二次修改呢?可以继续git add
再git commit
,也可以别着急提交第一次修改,先git add
第二次修改,再git commit
,就相当于把两次修改合并后一块提交了:
第一次修改 -> git add
-> 第二次修改 -> git add
-> git commit
二、撤销修改
第一步,对readme.txt文件进行修改:
➜ testcase git:(master) ✗ cat readme.txt Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes of files.
在准备提交前,猛然发现了stupid boss
可能会丢掉这个月的奖金!
既然错误发现得很及时,就可以很容易地纠正它。可以删掉最后一行,手动把文件恢复到上一个版本的状态。
第二步,先不手动删掉最后一行,用git status
查看一下:
➜ testcase git:(master) ✗ git status On branch master 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: readme.txt no changes added to commit (use "git add" and/or "git commit -a")
输出结果里,Git会告诉你,git checkout -- file
可以丢弃工作区的修改。
第三步:
➜ testcase git:(master) ✗ git checkout -- readme.txt
命令git checkout -- readme.txt
意思就是,把readme.txt
文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt
自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt
已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit
或git add
时的状态。
现在,看看readme.txt
的文件内容:
➜ testcase git:(master) cat readme.txt Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes of files.
从输出结果,可以看出文件内容复原了。
-------------------------------
另外一种情况,不旦写了些错误的内容,还git add
到暂存区了:
➜ testcase git:(master) ✗ cat readme.txt Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage. Git tracks changes of files. A stupid boss.
➜ testcase git:(master) ✗ git add readme.txt
在commit
之前,发现了这个问题。用git status
查看一下,修改只是添加到了暂存区,还没有提交:
➜ testcase git:(master) ✗ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: readme.txt
Git同样告诉我们,用命令git reset HEAD <file>
可以把暂存区的修改撤销掉(unstage),重新放回工作区:
➜ testcase git:(master) ✗ git reset head readme.txt
Unstaged changes after reset:
M readme.txt
git reset
命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD
时,表示最新的版本。
再用git status
查看一下,现在暂存区是干净的,工作区有修改:
➜ testcase git:(master) ✗ git status On branch master 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: readme.txt no changes added to commit (use "git add" and/or "git commit -a")
还记得如何丢弃工作区的修改吗?
➜ testcase git:(master) ✗ git checkout -- readme.txt
➜ testcase git:(master) git status
On branch master
nothing to commit, working directory clean
➜ testcase git:(master)
小结:
小结
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>
,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。