iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 7
1
DevOps

Git 其然,Git 其所以然系列 第 7

Git Workspaces

  • 分享至 

  • xImage
  •  
# Outline
一、前言
二、實驗
三、小結
A、待敘項目

# TL;DR
...

# Updated
2019-10-06: 更新文章結構

在雙十連假前,此系列文每天的發文時都會以最簡陳述為主,以求在繁忙的日常中,至少能先維持挑戰鐵人賽的進度,並且逐漸拓展思路與系列結構。預期會在國慶連假將本篇文章論述完整。

一、前言

常說 Git 不是記錄差異,而是紀錄快照。透過前幾天的說明,我們了解 Git 的會為每一個內文不同的檔案進行記錄,然後每個 Commit 其實只是指向了不同的 Tree Object,所以的確就像是為每個版本拍一張照片一樣。

那麼 Git 又是怎麼紀錄當前更動但還沒 commit 的狀態呢?其實前天文章的某個目錄結構就有讓這個重要角色露臉了,那就是 .git/index 這個檔案,讓我先回憶一下當時的結構吧!

二、實驗

# [Repo] f47eca7 @ dot-git
# [Repo] 5626a0e @ lab
# Location: ~/how-git-works-lab
$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── index
├── logs
│   └── ......
├── objects
│   └── ......
└── refs
    └── heads
        └── master

Index 是一個二進位檔案,無法透過 cat 去解析,若真的要暸解這個檔案記錄了什麼,就只能透過 Git 提供的另一個指令 —— git ls-file

# [Repo] f47eca7 @ dot-git
# [Repo] 5626a0e @ lab
# Location: ~/how-git-works-lab
$ git ls-files --stage
100644 a2beefd59223ea16000788d77e62f96bdaf23c7c 0	README.md
100644 4228d0cd48b9ed4395a23641c6292442b1af4994 0	src/app.rb

透過了這個指令,我們看到裡頭紀錄了該檔案的權限、對應 Git Object 的 SHA-1 值、以及對應的目錄位址。

這時候如果我們做了一些變動,像是新增、修改、刪除,在尚未把變動加入 index 時,index 檔案紀錄的資訊是沒有變化的:

# [Repo] f47eca7 @ dot-git
# [Repo] 5626a0e @ lab
# Location: ~/how-git-works-lab
$ echo 'puts "Yo"' >> src/app.rb
$ echo '# Model' >> src/model.rb
$ rm README.md
$ git ls-files --stage
100644 a2beefd59223ea16000788d77e62f96bdaf23c7c 0	README.md
100644 4228d0cd48b9ed4395a23641c6292442b1af4994 0	src/app.rb

但當我們加入 index 後,得出來的結構就更新了:

# [Repo] f47eca7 @ dot-git
# [Repo] 5626a0e @ lab
# Location: ~/how-git-works-lab
$ git add ./
$ git ls-files --stage
100644 bfdb6da6fc74e47e4328b1f60d55b3522d354c5d 0	src/app.rb
100644 50d91a6239ed5052fb5d5cdd3c4162d82161502d 0	src/model.rb

而同時,這些變動過的檔案也會以 Git Blob Object 儲存起來:

# [Repo] f47eca7 @ dot-git
# [Repo] 5626a0e @ lab
# Location: ~/how-git-works-lab
$ tree .git/objects/
.git/objects/
├── 42
│   └── 28d0cd48b9ed4395a23641c6292442b1af4994
├── 45
│   └── 1a871aa3a41aa0019cbe48980f18580efd6c7c
├── 50
│   └── d91a6239ed5052fb5d5cdd3c4162d82161502d
├── 65
│   └── 0e0dd9f112a14a0be19b3143a5eacee882e1bb
├── 8e
│   └── f377c8dc629dd200fa03aa10a48fb1a3efca19
├── a2
│   └── beefd59223ea16000788d77e62f96bdaf23c7c
├── b4
│   └── 2533e454e5d2692d7f0d96e2a8ed699de200e8
├── bf
│   └── db6da6fc74e47e4328b1f60d55b3522d354c5d
├── cb
│   └── 089cd89a7d7686d284d8761201649346b5aa1c
├── f4
│   └── 7eca7b5d0a157583076c66d470b1eb032822ac
├── fa
│   └── 5e6af79e30fc26ab4acbd96388fde22b4c2f36
└── fd
    └── d241767aec1614be16cd718e5baae6ba0cab4b

三、小結

所以其實 Git 是一個不斷新增的版本控制系統,Git 不會刪除被記錄下來的檔案,有修改過的檔案都會被當作新的檔案被加入,然後再重新指向到新檔案而已。

透過 index 紀錄的資訊以及當前 commit 的 Tree Object,Git 就可以比對出差異,有 index 與 commit 的差異,也有 index 和當前 Workspace 的差異。

A、待敘項目

  • 說明 workspace、index、repository 的概念。

上一篇
Git Reference
下一篇
Git Remote
系列文
Git 其然,Git 其所以然31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言