对象与目录的关系
git add
- 暂存区的目录树被更新
- 同时工作区修改或新增的文件内容被写入到对象库中的一个新的对象中
git commit
- 将暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树(?副本还是指针)
git rm --cached <file>
- 会直接从暂存区删除文件,工作区则不做出改变。
git reset HEAD
- 暂存区的目录树会被master 分支指向的目录树所替换,但是工作区不受影响。
git checkout -- <file>
- 会用暂存区目录树指定的文件替换工作区的文件。
- 这个操作很危险,会清除工作区中未添加到暂存区的改动。
git checkout HEAD <file>
- 会用 HEAD 指向的 master 分支中的指定文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
版本库丢失目前文件的索引?文件仍可回退;工作区文件被替换,且未加入对象库,无法回退
- –hard 是 reset 命令唯一的危险用法,它也是 git 会真正地销毁数据的 几个操作之一。其他任何形式的 reset 调用都可以轻松撤消,但是 –hard 选项不能,因 为它强制覆盖了工作目录中的文件。若该文件还未提交,git 会覆盖它从而导致无法恢复。
文件状态
首先对于任何一个文件, 在 Git 内都只有四种状态: 未跟踪 (untracked)、未修改 (unmodified)、已修改 (modified)、已暂存 (staged)
未跟踪
- 表示没有跟踪(add)某个文件的变化,使用git add即可跟踪文件
- 工作区文件,未添加对象,易失
未修改
- 表示某文件在跟踪后一直没有改动过或者改动已经被提交
- 工作区与对象库文件一致,且暂存区和版本库的目录树均指向此文件
已修改
- 表示修改了某个文件,但还没有加入(add)到暂存区中
- 工作区和对象库不一致,暂存区和版本库的目录树均指向此对象库文件
已暂存
- 表示把已修改的文件放在下次提交(commit)时要保存的清单中
- 第一次add时:对象库文件与工作区文件一致,暂存区指向对象库中此文件,版本库目录树无此文件指向
- 后续add修改版本时:对象库存在工作区修改前后的两版,工作区为新版文件,暂存区指向对象库中的新版文件,版本库目录树指向对象库中旧版文件
转换形式
Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged
Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified