工作区和暂存区
工作区
在我们自己电脑中,里面有.git文件夹的那个目录,我们一般叫做git工作区,但是请注意.git目录并不属于工作区,请勿轻易对.git目录中的文件进行删改
版本库
工作区中的.git目录,这个目录不算做工作区的一部分,确切的来讲,.git目录即是版本库
.git 版本库里面都有什么?
有暂存区stage,还有分支,目前只有master 还有我们指向当前版本的指针HEAD等
演示版本从工作区到暂存区再到版本库的过程
-
修改readme.txt,内容改为如下内容
$ vi readme.txt Git is a distributed version control system. Git is free software distributed under the GPL. Git has a mutable index called stage.
新曾一个文件LICENSE,内容随便
-
查看版本库状态
$ 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 Untracked files: (use "git add <file>..." to include in what will be committed) LICENSE no changes added to commit (use "git add" and/or "git commit -a")
Git status 明确告诉我们,readme.txt 被修改了,然后LICENCE文件在版本库中没有历史足迹untracked
ok,那我们把这两个文件都加进版本库,再看状态
$ git add readme.txt LICENSE $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: LICENSE modified: readme.txt
上面的结果说,在master 分支上,有改变可以被提交,分别是,新文件LICENSE和已经修改的文件readme.txt
那么,实际上这两个待提交的文件,现在所处的位置是在版本库的暂存区
那么,再来思考一下,我们将我们新增或修改的文件进行git add 之后,其实文件就都是进入了暂存区,等待提交。
所以,我们可以进行多次add后再一次性将所有本次改动进行一次提交到版本库
$ touch readme2.txt $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: LICENSE modified: readme.txt Untracked files: (use "git add <file>..." to include in what will be committed) readme2.txt $ git add readme2.txt $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: LICENSE modified: readme.txt new file: readme2.txt $ git commit -m 'understand stage' [master e17c4d4] understand stage 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 LICENSE create mode 100644 readme2.txt
结果可见,git commit 的时候提交了三个文件的改变,LICENSE和readme.txt 是以创建的形式加入到版本库的
那么再来看我们版本库的status
$ git status On branch master nothing to commit, working tree clean
没有需要提交的内容,说明暂存区已经被清空了,那么现在我们版本库的暂存区是空的
管理修改
这一部分,我们重点关注一个点,git版本管理到底管理的是什么呢?不是管理的文件吗?
git版本管理,管理和跟踪的是每一次对版本库中的内容的修改而非具体的某个文件。
那么问题来了,git中如何定义修改?
git中把新增文件、删除文件、新增内容、删除内容、修改内容都定义为对版本库的修改
在工作区的readme.txt中新增一行内容
$ vi 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.
加入到暂存区
$ git add readme.txt $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: readme.txt
然后再次修改readme.txt文件
$ vi 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 commit -m 'git tracks files' [master 400bdba] tracks files 1 file changed, 1 insertion(+) $ 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 diff HEAD -- readme.txt来看看工作区的内容与当前版本库的内容的区别
$ git diff HEAD -- readme.txt --- 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.
从返回结果中能看出什么?工作区的内容修改还是存在的,且没有被提交
说明了什么?
是的,第二次的修改并没有提交,说明了很多事情,
第一:说明git管理的并不是文件,如果是文件的话那么提交的时候,要么无法提交,要么将第二次修改也一并提交
第二:说明git提交的时候,只会提交加入到暂存区的内容,对于没有加入到暂存区的修改记录,git提交时,不予处理
$ git add readme.txt $ git commit -m 'append of files' [master 65d43dc] append of files 1 file changed, 1 insertion(+), 1 deletion(-) $ git status On branch master nothing to commit, working tree clean
如上就已经把第二次修改添加到暂存区,并提交到版本库了
撤销修改
撤销修改这里提到有如下几种撤销
-
撤销当前工作区的修改
对当前工作区的内容进行了修改,已经保存,但是还没有添加到暂存区的情况
修改readme.txt
$ vi 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. My stupid boss still prefers SVN.
加完之后,发觉用词不当,想回退到修改前的状态,当然,我们可以手工去文件中删除这一行,这在修改少量内容的情况下是可行的,但是仔细想一想,如果我们在工作的时候做了大量内容的修改,甚至于自己都记不清修改了哪些地方的时候,手工修改还可行吗?虽然说git能够帮我们记住我们所有的修改内容,但是如果大量内容手工还原的话,会不会太麻烦了啊,那么我们采用git的方式方便快捷的进行还原吧
$ 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 add 将文件加入到版本库的暂存区,当做将要提交的内容
(use "git add <file>..." to update what will be committed)
-
用 git checkout — file… 丢弃工作区的修改
(use "git checkout -- <file>..." to discard changes in working directory)
ok,那么我们现在用 git checkout — readme.txt,丢弃工作区的修改试试看
-
$ git checkout -- readme.txt $ git status On branch master nothing to commit, working tree clean $ vi 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.
好了,果然,工作区的修改内容被撤销了,内容还原到了版本库中当前版本的状态。
-
撤销对暂存区的修改
对当前工作区的内容作出了修改,已经保存,并且已经添加到版本库的暂存区,但是还没有进行commit
那么,我们要怎么做呢?
$ vi 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. My stupid boss still prefers SVN. $ git add readme.txt $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: readme.txt
git status 告诉我们,现在版本库的暂存区中有一个对readme.txt文件的修改,
我们可以有两种处理方式:
- 一种是提交到版本库 git commit
- 另一种是将暂存区的修改排除到暂存区外,也就是从暂存区剔除,放回工作区 git reset HEAD file...
那么,我们这里选择第二种操作,将修改剔除到暂存区之外,放回工作区
$ git reset HEAD readme.txt Unstaged changes after reset: M readme.txt $ 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")
ok,现在当前修改已经从版本库的暂存区剔除,放回工作区了,如果需要再把工作区的内容还原到版本库中的当前版本,使用git checkout — readme.txt 即可
-
撤销对版本库的修改
如果对当前工作区的内容做了修改,已经添加到暂存区,也已经提交到了版本库,咋办呢?
没关系,使用版本管理中的版本回退就可以回退到当前版本的上一个版本了,但是会有log历史记录哦
$ git checkout —hard HEAD^
-
删除文件
git 版本管理中,删除文件是记做一次修改的
$ touch test.txt
$ git add test.txt
$ git commit -m 'add file test.txt'
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test.txt
$ rm test.txt
$ 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 status 告诉我们有一个文件被删除了,并且给出了两种处理方式,
-
一种是使用git add/rm 来将删除放入暂存区,再提交,这里使用git add或者是 git rm 是一样的效果,我们都试一次
$ git add test.txt $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: test.txt $ git commit -m 'delete file test.txt' 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test.txt
再用 git rm 再试一次
$ git reset --hard HEAD^ HEAD is now at ceebf26 add file test.txt $ rm test.txt 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 test.txt rm 'test.txt' $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: test.txt $ git commit -m 'delete file test.txt' 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test.txt $ git status On branch master nothing to commit, working tree clean
如上,就已经完成了将文件从版本库删除
-
另一种是从版本库中将文件拉回到当前工作区,这种方式主要解决误删的情况
其实这里的操作是使用撤销修改的操作,即可从版本库中再次将文件获取出来,这里我们先回退版本库到添加test.txt的版本,在进行相应操作
$ git reset --hard HEAD^ HEAD is now at ceebf26 add file test.txt $ rm test.txt $ ls LICENSE readme.txt readme2.txt $ 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 checkout -- test.txt $ git status On branch master nothing to commit, working tree clean $ ls LICENSE readme.txt readme2.txt test.txt
好啦,文件又回来啦