|   一、工作区和暂存区 
 Git和其他版本控制系统的不同之处就是有暂存区的概念。暂存区是Git非常重要的概念,弄明白了暂存区,就弄明白了Git的很多操作到底干了什么。 
 前面讲了向Git版本库里提交文件分两步执行: 用git add把文件添加进去,实际上就是把文件修改添加到暂存区;用git commit提交更改,实际上就是把暂存区的内容提交到当前分支。
 简单理解为,需要提交的文件修改全部放到暂存区,然后,一次性提交暂存区的所有修改。因为我们创建Git版本库时,Git自动为我们创建了一个master分支,所以git commit就是往master分支上提交更改。 下面开始实战,先对 readme.txt 加上一行内容,然后再新建一个LICENSE文本文件。 Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
 先用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:   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告诉我们 readme.txt 被修改了,而 LICENSE 还从来没有被添加过,所以它的状态是Untracked。 现在把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
 现在,暂存区的状态就变成这样了: 
 所以,git add命令就是把要提交的修改放到暂存区(Stage),然后执行git commit就可以一次性把暂存区的所有修改提交到分支。提交后如果没有对工作区做任何修改,那么工作区就是“干净”的。 $ git status
On branch master
nothing to commit, working tree clean
 现在版本库变成了这样,暂存区就没有任何内容了: 
 
 二、管理修改 
 在Git中是对修改进行跟踪并管理,而非文件。比如新增或删除了一行,更改了某些字符,甚至创建一个新文件,这都算是修改,都会被Git跟踪并管理。下面通过实验来说明。 第一步,为 readme.txt 加一行内容: $ cat readme.txt
Git is a distributed version control system.
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: $ cat readme.txt 
Git is a distributed version control system.
Git tracks changes of files.
 提交: $ git commit -m "git tracks changes"
[master 519219b] git tracks changes
 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管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了。 
 三、撤销修改假如你在readme.txt中添加了一行内容,在提交前你又删掉这一行内容,手动把文件恢复到上一个版本的状态。用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:   readme.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 文件在工作区的修改全部撤销,这里有两种情况:  readme.txt 自修改后还没有被放到暂存区,现在撤销修改就回到和版本库一模一样的状态; readme.txt 已经添加到暂存区后,又作了修改,现在撤销修改就回到添加到暂存区后的状态。
 总之就是让文件回到最近一次git commit或git add时的状态。  
 git checkout -- file命令中的--很重要,没有--,就变成了 “切换分支” 的命令。
 假如已经把错误代码git add到暂存区了,但在commit之前发现了这个问题。用git status查看一下,修改只是添加到了暂存区,还没有提交: $ 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),重新放回工作区: $ git reset HEAD readme.txt
Unstaged changes after reset:
M	readme.txt
  
 git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
 查看一下状态,现在暂存区是干净的,工作区有修改: $ 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
 
 四、删除文件在Git中删除也算修改操作,例如新建一个文件test.txt并提交: $ 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
 然后再把 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命令把误删的文件恢复到最新版本。 $ git checkout -- test.txt
 
 五、总结 每次修改,如果不用git add到暂存区,那就不会加入到commit中。 当改乱了某个文件的内容,想丢弃工作区的修改时,用命令git checkout -- file。 当改乱了某个文件的内容并添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了场景1,第二步按场景1操作。 假设把错的文件从暂存区提交到了版本库,想要撤销本次提交,只能进行版本回退。 命令git rm用于删除版本库里的文件。如果不小心误删了,但是文件已经提交到版本库,那么就可以从版本库将文件进行还原,但是只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
 感谢大家的耐心阅读,如有建议请私信或评论留言
 |