刘聪 3 jaren geleden
bovenliggende
commit
78d46fddf7
3 gewijzigde bestanden met toevoegingen van 283 en 0 verwijderingen
  1. BIN
      Git/Image/2
  2. BIN
      Git/Image/3
  3. 283 0
      Git/README.md

BIN
Git/Image/2


BIN
Git/Image/3


+ 283 - 0
Git/README.md

@@ -194,3 +194,286 @@ git config --global alias.ci "commit -s"
 
 ## Git暂存区
 
+`git log --stat`
+
+`git log` 查看提交日志,`--stat`可以看到每次提交的文件变更统计
+
+### 不能直接提交吗
+
+修改welcome.txt文件,随后通过`git diff`命令看到修改后的文件与版本库中文件的差异
+
+```bash
+root@cong:~/demo# git diff
+diff --git a/welcome.txt b/welcome.txt
+index b2dcbb2..e4311de 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,2 @@
+ hello wrold
+-
++qwer
+```
+
+直接通过`git commit -m "appent line"`执行提交命令
+
+```bash
+root@cong:~/demo# git commit -m "append line"
+On branch master
+Changes not staged for commit:
+        modified:   welcome.txt
+
+no changes added to commit
+```
+
+可见未添加,直接提交文件时会提交失败,通过`git status`查看文件状态,可以看到文件处于修改且未添加的状态,也就是说对修改文件需要先`git add welcome.txt`添加到提交任务中,之后才能提交
+
+在add之后,再次查看`git diff`,输出为空;当与HEAD(版本库的头指针)进行比较时`git diff HEAD`,可以发现差异
+
+```bash
+root@cong:~/demo# git diff HEAD
+diff --git a/welcome.txt b/welcome.txt
+index b2dcbb2..e4311de 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,2 @@
+ hello wrold
+-
++qwer
+```
+
+执行`git status`,查看状态输出
+
+```bash
+root@cong:~/demo# git status
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+        modified:   welcome.txt
+```
+
+对比两次`git status`的输出,第一次"Changes not staged for commit:",第二次"Changes to be committed:"
+
+- 在`git add`执行之前,`git status`的提示表示,工作区当前的文件与处于中间状态——提交任务(提交暂存区,stage)中的文件相比有改动
+- 在`git add`执行之后,`git status`的提示表示,版本库中的文件与处于中间状态——提交任务(提交暂存区,stage)中的文件相比有改动
+
+更好的理解暂存区,可以再次修改welcome.txt文件,之后再次查看`git status`
+
+```bash
+root@cong:~/demo# git status
+On branch master
+Changes to be committed:
+  (use "git reset HEAD <file>..." to unstage)
+
+        modified:   welcome.txt
+
+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:   welcome.txt
+```
+
+会发现welcome.txt文件处于混合状态,不但版本库中最新提交的文件与处于中间状态——提交任务(提交暂存区,stage)中的文件相比有改动,而且工作区当前的文件与处于中间状态——提交任务(提交暂存区,stage)中的文件相比也有改动
+
+那么此时welcome.txt有三个不同的版本,一个在工作区,一个在暂存区,一个在版本库,通过`git diff`查看不同状态下的文件的差异
+
+- `git diff`查看工作区文件和暂存区文件的差异(我这里在文件后面加了"1234")
+- `git diff HEAD`查看工作区文件和版本库文件的差异(我这里是加过"qwer 1234")
+- `git diff --cached`查看暂存区文件和版本库文件的差异
+
+```bash
+root@cong:~/demo# git diff
+diff --git a/welcome.txt b/welcome.txt
+index e4311de..88f2600 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,4 @@
+ hello wrold
+ qwer
++1234
++
+root@cong:~/demo# git diff HEAD
+diff --git a/welcome.txt b/welcome.txt
+index b2dcbb2..88f2600 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,4 @@
+ hello wrold
++qwer
++1234
+
+root@cong:~/demo# git diff --cached
+diff --git a/welcome.txt b/welcome.txt
+index b2dcbb2..e4311de 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,2 @@
+ hello wrold
+-
++qwer
+```
+
+在`git commit -m "append line qwer"`之后,再次查看`git status`
+
+### 理解Git暂存区
+
+执行`git checkout`命令,撤销工作区中welcome.txt文件尚未提交的修改
+
+```bash
+root@cong:~/demo# git checkout welcome.txt
+root@cong:~/demo# git status
+On branch master
+nothing to commit, working tree clean
+```
+
+通过一下命令,查看`.git/index`文件的时间戳
+
+```bash
+root@cong:~/demo# git status -s
+root@cong:~/demo# ls --full-time .git/index
+-rw-r--r-- 1 root root 145 2022-02-24 10:07:18.571978495 +0800 .git/index
+root@cong:~/demo# touch welcome.txt
+root@cong:~/demo# git status -s
+root@cong:~/demo# ls --full-time .git/index
+-rw-r--r-- 1 root root 145 2022-02-24 10:07:45.931483425 +0800 .git/index
+```
+
+会发现`.git/index`文件的时间戳改变了,也就是说当执行`git status`命令扫描工作区改动的时候,先依据`.git/index`文件中记录的(用于追踪工作区文件的)时间戳、长度等信息判断工作区文件是否改变
+
+如果工作区文件的时间戳改变了,说明文件的内容可能被改变,需要打开文件,读取文件内容,与更改之前的原始文件相比较,判断文件内容是否被更改。如果文件内容没有被改变,则将该文件新的时间戳记录到`.git/index`文件中。
+
+因为使用时间戳、文件长度信息进行比较要比通过文件内容比较快很多,这也是git高效的原因之一
+
+![](./Image/2)
+
+文件`.git/index`实际上就是一个包含文件索引的目录树,像是一个虚拟的工作区。在这个虚拟的工作区的目录树中,记录了文件名和文件的状态信息(时间戳和文件长度),文件的内容并没有存储在其中,而是保存在Git对象库`.git/objects`目录中,文件索引建立了文件和对象库中对象实体之间的对应
+
+- 当对工作区修改(或新增)的文件执行`git add`命令时,暂存区的目录树将更新,同时工作区修改(或新增)的文件内容会被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中
+
+- 执行提交操作`git commit`时,暂存区的目录树会被重写,会被master分支指向的目录树所替换,但是工作区不受影响
+- 当执行`git reset HEAD`时,暂存区的目录树会被重写,会被master分支指向的目录树所替换,但是工作区不受影响
+- 当执行`git rm --cached <file>`时,会直接从暂存区删除文件,工作区不做出改变
+- 当执行`git checkout .`或`git checkout --<file>`时,会用暂存区全部的文件或指定的文件替换工作区的文件(会清除工作区中未添加到暂存器的改动)
+- 当执行`git checkout HEAD .`或`git checkout HEAD <file>`时,会用HEAD指向的master分支中的全部或部分文件替换暂存区和工作区中的文件(不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动)
+
+### git diff
+
+#### 工作区、暂存区和版本库的目录树浏览
+
+对于HEAD指向的目录树,可以使用Git底层命令 `ls-tree` 来查看
+
+```bash
+root@cong:~/demo# git ls-tree -l HEAD
+100644 blob e4311de49561b359eb23fefc7badb504bb3ed680      17    welcome.txt
+```
+
+> -l 命令可以查看文件大小
+
+- 上述命令的输出值从左往右理解
+  - `100644`: 权限管理,文件属性,代表`644`->`rw-r--r--`
+  - `blob`: Git对象库中是一个blob对象(文件)
+  - `e4311de49561b359eb23fefc7badb504bb3ed680`: 对象库中对象的ID——一个40位的SHA1哈希值格式的ID
+  - `17`: 文件大小
+  - `welcome.txt`文件名
+
+浏览暂存区目录树之前,使用`git clean -fd`命令清除当前工作区中没有加入版本库的目录和文件,使用`git checkout .`用暂存区内容刷新工作区
+
+```bash
+vim welcome.txt     # 修改welcome.txt文件
+mkdir a/b/c         # 新建文件夹
+cd a/b/c
+vim hello.txt       # 新建a/b/c/hello.txt文件并添加内容
+git add .           # 将内容添加到暂存区
+```
+
+做好一系列准备之后,通过`git ls-files -s`查看暂存区目录树
+
+```bash
+root@cong:~/demo# git ls-files -s
+100644 e86bb55b3cc7cb0b5b8b5a86790a4e71d94d5b1a 0       a/b/c/hello.txt
+100644 d69370cbd3a75a6d62e1e0cf7a7590377c72b070 0       welcome.txt
+```
+
+这里前面两项跟HEAD目录树一样,第三项`0`表示的是暂存区编号
+
+```bash
+root@cong:~/demo# git write-tree |xargs git ls-tree -l -r -t
+040000 tree 63e054994c74908fd0f17cf77aed955a6174fd05       -    a
+040000 tree bcd5aa9636b4192a14115cf029f3cd03b5ff972c       -    a/b
+040000 tree b59f4c72367471830d44da6a498675b791d6a4b7       -    a/b/c
+100644 blob e86bb55b3cc7cb0b5b8b5a86790a4e71d94d5b1a      11    a/b/c/hello.txt
+100644 blob d69370cbd3a75a6d62e1e0cf7a7590377c72b070      16    welcome.txt
+```
+
+### git diff
+
+![](./Image/3)
+
+通过使用不同的参数调用`git diff`命令,可以对工作区、暂存区和HEAD中的内容进行两两比较
+
+1. 工作区和暂存区比较
+
+```bash
+root@cong:~/demo# git diff
+diff --git a/welcome.txt b/welcome.txt
+index d69370c..915ffc6 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,2 @@
+ llo wrold
+-aqwer
++aasdfsafqwer
+```
+
+2. 暂存区和HEAD比较
+
+```bash
+root@cong:~/demo# git diff --cached
+diff --git a/a/b/c/hello.txt b/a/b/c/hello.txt
+new file mode 100644
+index 0000000..e86bb55
+--- /dev/null
++++ b/a/b/c/hello.txt
+@@ -0,0 +1 @@
++aqwerqwre:
+diff --git a/welcome.txt b/welcome.txt
+index e4311de..d69370c 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,2 @@
+-hello wrold
+-qwer
++llo wrold
++aqwer
+```
+
+3. 工作区和HEAD比较
+
+```bash
+root@cong:~/demo# git diff HEAD
+diff --git a/a/b/c/hello.txt b/a/b/c/hello.txt
+new file mode 100644
+index 0000000..e86bb55
+--- /dev/null
++++ b/a/b/c/hello.txt
+@@ -0,0 +1 @@
++aqwerqwre:
+diff --git a/welcome.txt b/welcome.txt
+index e4311de..915ffc6 100644
+--- a/welcome.txt
++++ b/welcome.txt
+@@ -1,2 +1,2 @@
+-hello wrold
+-qwer
++llo wrold
++aasdfsafqwer
+```
+
+### 不要使用 git commit -a
+
+`git commit -a`对本地所有变更的文件执行提交操作,包括对本地修改的文件和删除的文件,但不包括违背版本库跟踪的文件
+
+使用该命令确实是快,但是丢失了Git暂存区带给用户最大的好处:对提交内容进行控制的能力
+
+###