能够认为使用Git时,咱们会遇到3个空间:工做目录、索引、版本库。咱们关心的,就是在新建、修改等操做时,这三者之间发生了怎样的变化。git
笼统的讲,就是在工做目录下编辑,在索引中积累修改,而后把索引中累计的修改做为一次性的变动提交给版本库。shell
这就意味着,能够在最终提交前添加、删除、移动或者重复编辑文件,只有在提交后才会在版本库里实现累计的变动。bash
本章将介绍如何管理索引和文件。测试
Git的索引不包含任何文件内容,它仅仅追踪你想要提交的那些内容。这一点,咱们能够在后面的图示中看到。当git commit时,会经过检查索引而不是工做目录来找到提交的内容。spa
在暂存的过程当中,git diff将会是一个很是有用的命令。命令行
git diff 显示仍留在工做目录中且为暂存的变动。code
git diff –cached 显示已经暂存而且要在下一次提交的变动。对象
Git将全部的文件分为3类:已追踪的、被忽略的、未追踪的。blog
这里经过建立一个全新的工做目录并处理一下文件来看一下这些不一样类别的文件。索引
在工做目录中常常会产生一下临时文件,在版本库中这些文件一般是不该该被当作源文件追踪的。
为了让Git忽略这些文件,只须要将该文件名添加到一个特殊的文件.gitignore中就能够了
上图中的步骤中咱们看到了这种变化。须要注意的是,虽然.gitignore对于Git是个特殊的文件,可是也须要手动的添加到索引中。
git add将暂存一个文件。看看例子就行了。
[root@flower1 my_stuff]# git status # On branch master # # Initial commit # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # .gitignore # data nothing added to commit but untracked files present (use "git add" to track) [root@flower1 my_stuff]# git add data .gitignore [root@flower1 my_stuff]# git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: .gitignore # new file: data #
[root@flower1 my_stuff]# git ls-files --stage
上面的这个实验蛮有意思。当咱们修改了data这个文件后,文件自己的SHA1散列码已经改变,可是git ls-files –stage没有发生变化。只有到使用git add命令后才发生变化。这是由于,索引以后指向已经存在于对象库中的blob对象。
git commit -a或者-all选项会致使执行提交前自动暂存全部未暂存的和未追踪的文件变化,包括从工做副本中删除已追踪的文件。
作个试验来验证一下。这里就不截图了。
试验的结果是:上面的说法感受有歧义。所谓的自动暂存,是有前提的,前提是这些文件自己就已经在版本库中或者已经在索引中。(这是我测试的结果,不知是否真的正确)
Git能够在索引中或者同时在索引和工做目录中删除一个文件,可是不能删除该文件在版本库中的历史记录。
git rm -f file1会从索引和工做目录中同时删除
git rm –cached file2 仅删除索引中的文件
下面验证一下:
[root@flower1 committest]# ls newfile notyet.txt ready.txt [root@flower1 committest]# rm newfile rm: remove regular file `newfile'? y [root@flower1 committest]# ls notyet.txt ready.txt [root@flower1 committest]# echo "new file" > newfile [root@flower1 committest]# ls newfile notyet.txt ready.txt [root@flower1 committest]# git add newfile [root@flower1 committest]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: newfile # [root@flower1 committest]# git rm --cached newfile rm 'newfile' [root@flower1 committest]# git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # newfile nothing added to commit but untracked files present (use "git add" to track) [root@flower1 committest]# ls newfile notyet.txt ready.txt
上面的试验,使用了—cached参数,工做目录中的文件没有删除。
[root@flower1 committest]# git add newfile [root@flower1 committest]# git rm -f newfile rm 'newfile' [root@flower1 committest]# ls notyet.txt ready.txt
想要移除一个已经提交的文件,经过git rm和git commit的组合命令便可实现。
这里仅用命令行说明一下吧 。
[root@flower1 committest]# ls notyet.txt ready.txt [root@flower1 committest]# git mv ready.txt ready.txt.bak [root@flower1 committest]# git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # renamed: ready.txt -> ready.txt.bak # [root@flower1 committest]# git commit -m "new data ty" [master 2a9b527] new data ty 1 files changed, 0 insertions(+), 0 deletions(-) rename ready.txt => ready.txt.bak (100%) [root@flower1 committest]# git log ready.txt.bak commit 2a9b52785b94c45852276c4febb4e05d9e25de1f Author: nextflowertest <test@qq.com> Date: Wed Dec 2 22:16:59 2015 +0800 new data ty [root@flower1 committest]# get log --follow ready.txt.bak -bash: get: command not found [root@flower1 committest]# git log --follow ready.txt.bak commit 2a9b52785b94c45852276c4febb4e05d9e25de1f Author: nextflowertest <test@qq.com> Date: Wed Dec 2 22:16:59 2015 +0800 new data ty commit 1e5f4c75d4b1c6055fe68392fe0a431d9039870a Author: nextflowertest <test@qq.com> Date: Wed Dec 2 22:01:09 2015 +0800 yes [root@flower1 committest]# ls notyet.txt ready.txt.bak
略。
这个文件中的内容能够比较灵活,格式以下:
当有多个层次的目录都有.gitignore文件时,优先级从高到低以下:
这一节主要经过几张图来讲明各类变化。
下面这张图展现的是提交了2个文件的版本库视图。工做目录、索引以及对象库都是同步和一致的。
接着咱们在工做目录里对file1进行编辑,如今它的内容包含“quux.”
而后使用git add命令,将file1内容提交到对象库中:
最后,执行git commit命令: