Skip to main content

《Git 权威指南》第三篇 Git独奏 第5章 Git暂存区

6 min read

[toc]

前言

本系列文章是针对计算机经典书籍《Git 权威指南》的精简版学习笔记,方便大家快速了解内容以及速记,欢迎订阅

上一篇文章,我们学习了创建版本库的几个命令,不熟悉的同学可以参考 Git初始化

  • git log --stat
  • 可以看到每次提交的文件变更统计

5.1 修改不能直接提交吗

  • echo "Nice to meet you" >> welcome.txt
  • git diff
  • 可以看到修改后的文件与本库(与本地比较的不是版本库中的文件,而是一个中间状态的文件)中的文件的差异
  • 工作区与提交任务中相比的差异

diff --git a/welcome.txt b/welcome.txt

index 18832d3..9c2a787 100644

--- a/welcome.txt

+++ b/welcome.txt

@@ -1 +1,2 @@

Hello.

+Nice to meet you

  • 如果此时认为文件修改后可以直接提交,那就错了哦,
  • 尝试运行命令:git commit -m "Append a nice line."
  • 发现会运行不成功
  • 提交日志里面没有新的提交记录出现
  • 执行 git diff 可以看到和之前一样的结果,说明没有提交成功
  • git status查看文件状态,可以看到文件处于修改状态,
  • 精简模式 git status -s

➜ git commit -m "Append a nice line."

On branch master

Changes not staged for commit:

modified: welcome.txt

no changes added to commit

  • 所以如果想提交,需要利用 git add命令
  • git add welcome.txt
  • git diff HEAD
  • 工作区与HEAD相比
  • git diff --stagedgit diff --cached
  • 提交暂存区与版本库中文件的差异
  • git status -s
  • M位于第一列的含义
  • M welcome.txt
  • 版本库中的文件与处于中间状态--提交任务(提交暂存区,stage)中的文件相比有改动
  • M位于第二列的含义
  • 工作区当前的文件与处于中间状态--提交任务(提交暂存区,stage)中的文件相比有改动
  • M welcome.txt
  • 如果此时继续修改welcome.txt 文件
  • echo "Bye-Bye." >> welcome.txt
  • git status -s
  • MM welcome.txt
  • 不但版本库中最新提交的文件与处于中间状态--提交任务(提交暂存区,stage)中的文件相比有改动,而且工作区当前的文件处于中间状态--提交任务(提交暂存区,stage)中的文件相比也有改动
  • 现在再来提交
  • git commit -m "which version checked in?"
  • 如何证明提交成功呢
  • git log --pretty=oneline
  • git status -s
  • git diff

5.2 理解Git暂存区(stage)

  • git status 原理
  • 先依据.git/index文件中记录的时间戳,长度等信息判断工作区文件是否改变
  • 如果工作区文件的时间戳改变了,说明文件的内容可能改变了,需要打开文件,读取文件内容,与源文件做比较,
  • 如果文件内容没有改变,则将该文件新的时间戳记录到.git/index文件中
  • 使用时间戳,文件长度等信息进行比较要比通过文件内容比较要快得多
  • .git/index
  • 实际是一个包含文件索引的目录树,像一个虚拟的工作区
  • 记录了文件名和文件的状态信息(时间戳和文件长度,文件的内容没有存储在其中,而是保存在Git对象库.git/objects目录中

img

  • HEAD实际是指向master分支的一个 “游标”,所以图示的命令中出现HEAD的地方可以用master来替换
  • 图中的objects标识的区域为Git的对象库,实际位于 .git/objects 目录下,这一点会在后面的章节中重点介绍
  • 当对工作区修改(或新增)的文件执行git add命令时,暂存区的目录树将会被更新,同时工作区修改(或新增)的文件内容会被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中
  • 当执行提交操作(git commit)时,暂存区的目录树会写到版本库(对象库)中,master分支会做相应的更新,即master最新指向的目录树就是提交时原暂存区的目录树
  • 当执行git reset HEAD 命令时,暂存区的目录树会被重写,会被master指向的目录树所替换,但是工作区不受影响
  • 当执行git rm --cached <file> 命令时,会直接从暂存区删除文件,工作区则不做出改变
  • 但执行git checkout ., 或git checkout -- <file> 命令时,会用暂存区全部的文件或制定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动
  • 但执行git checkout HEAD . 或git checkout HEAD <file> 命令时,会用HEAD指向的master分支中的全部或者部分文件替换暂存区和工作区中的文件,这个命令也是极具危险性的,因为不但会清除工作区中的未提交的改动,也会清除暂存区中未提交的改动

5.3 Git Diff魔法

1. 工作区,暂存区和版本库的目录树浏览

➜ git ls-tree -l HEAD

100644 blob 7e12803b85898fd0ae42d0a793c3eaf9f0cdd66e 28 test.ini

100644 blob 9c2a787a930a7b547abdf71e47ab1a67de890832 24 welcome.txt

  • -l 参数可以显示文件的大小
  • 第一个字段是文件的属性(rw-r--r--)
  • 第二个字段说明是Git对象库中的一个blob对象(文件),
  • 第三个字段则是该文件在对象库中对应的ID--一个40位的SHA1哈希值格式的ID
  • 第四个字段是文件大小
  • 第五个字段是文件名
  • 清除当前工作区中没有加入版本库的文件和目录(非跟踪文件和目录)
  • git clean -fd
  • 用暂存区内容刷新工作区
  • git checkout .
2. Git diff 魔法

img

  • 工作区和暂存区比较
  • git diff
  • 暂存区和HEAD比较
  • git diff --cached
  • 工作区和HEAD比较
  • git diff HEAD

5.4 不要使用git commit -a

  • 好处
  • 减少用git add 命令标识变更文件的步骤
  • 坏处
  • 丢掉Git暂存区带给用户的最大好处:对提交内容进行控制的能力
5.5 搁置问题,暂存状态
  • git stash
  • 保存当前共奏进度
Loading Comments...