目录
管理修改
我们要讨论的就是,为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。
比如:han.txt添加一行内容
My name is hanjingyun.
Git is a version control system.
Git is free software.
-------------------------------------
I changed my text for the first time...
---------------------------------------
kuanglangkuanglang~~
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: han.txt
change again~~
My name is hanjingyun.
Git is a version control system.
Git is free software.
-------------------------------------
I changed my text for the first time...
---------------------------------------
kuanglangkuanglang~~
I am listening an English song
提交:
$ git commit -m "git tracks changes"
[master 96a3358] git tracks changes
1 file changed, 3 insertions(+), 1 deletion(-)
提交后,再看看状态:
$ 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: han.txt
no changes added to commit (use "git add" and/or "git commit -a")
会发现第二次的修改没有被提交,why?
look-->
第一次修改->git add ->第二次修改 ->git commit
前面说了,Git管理的是修改,当你用git add
命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit
只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
提交后,用git diff HEAD -- readme.txt
命令可以查看工作区和版本库里面最新版本的区别:
$ git diff HEAD -- han.txt
diff --git a/han.txt b/han.txt
index cb0396a..cbbc1f6 100644
--- a/han.txt
+++ b/han.txt
@@ -4,4 +4,6 @@ Git is free software.
-------------------------------------
I changed my text for the first time...
---------------------------------------
-kuanglangkuanglang~~
\ No newline at end of file
+kuanglangkuanglang~~
+
+I am listening an English song
\ No newline at end of file
可见,第二次修改确实没有被提交。
现在可以继续git add
再git commit
,也可以别着急提交第一次修改,先git add
第二次修改,再git commit
,就相当于把两次修改合并后一块提交了:
第一次修改 -> git add
-> 第二次修改 -> git add
-> git commit
好,现在,把第二次修改提交了,然后开始小结。
小结
理解了Git是如何跟踪修改的,每次修改,如果不用git add
到暂存区,那就不会加入到commit
中。
撤销修改
1、修改后现在及时发现了一个错误:
$ 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: han.txt
no changes added to commit (use "git add" and/or "git commit -a")
Git会告诉你,git checkout -- file
可以丢弃工作区的修改(删除也是一次修改,可撤销删除,后边又提到):
$ git checkout -- readme.txt
git checkout -- readme.txt
意思就是,把readme.txt
文件在工作区的修改全部撤销,就是让这个文件回到最近一次git commit
或git add
时的状态。
git checkout -- file
命令中的--
很重要,没有--
,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout
命令。
2、修改后git add到暂存区了
庆幸的是,在commit
之前,你发现了这个问题。用git status
查看一下,修改只是添加到了暂存区,还没有提交:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: han.txt
Git同样告诉我们,用命令git reset HEAD <file>
可以把暂存区的修改撤销掉(unstage),重新放回工作区:
$ git reset HEAD han.txt
Unstaged changes after reset:
M han.txt
git reset
命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD
时,表示最新的版本。
再用git status
查看一下,现在暂存区是干净的,工作区有修改:
$ 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: han.txt
还记得如何丢弃工作区的修改吗?
$ git checkout -- han.txt
$ git status
On branch master
nothing to commit, working tree clean
整个世界终于清静了!
3、假设你不但改错了东西,还从暂存区提交到了版本库,怎么办呢?
还记得穿梭版本一节吗?可以回退到上一个版本。不过,这是有条件的,就是你还没有把自己的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后面会讲到远程版本库,一旦你把stupid boss
提交推送到远程版本库,你就真的惨了……
小结
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file
。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>
,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考穿梭版本一节,不过前提是没有推送到远程库。
删除文件
在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt
到Git并且提交:
$ git add test.txt
$ git commit -m "add test.txt"
[master b84166e] add test.txt
1 file changed, 1 insertion(+)
create mode 100644 test.txt
一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm
命令删了:
$ rm test.txt
Git知道你删除了文件,因此,工作区和版本库就不一致了,git status
命令会立刻告诉你哪些文件被删除了:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm
删掉,并且git commit
:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
现在,文件就从版本库中被删除了。
小提示:先手动删除文件,然后使用git rm <file>和git add<file>效果是一样的。
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
$ git checkout -- test.txt
git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
小结
命令git rm
用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。