# 前言
上一篇文章,我們已經學會使用 git status
來查看檔案狀態,不過 git status
呈現的檔案狀態,好像不是只有 暫存 (stage) 與 未暫存 (unstage) 這麼簡單。
這篇文章我們來更細部的探討 Git 中,資料會出現的狀態。
預告一下:
文章預計會說明四個名詞定義,最後還會證明其中兩個名詞 未追蹤 等於 未暫存,整篇內容可能會讓新手看完覺得頭很暈!
如果你畏懼字詞解釋的話,可以直接滑到文章最底端,看結論。
# 已追蹤 (Tracked) 、未追蹤 (Untracked),已暫存 (Staged)、未暫存 (Unstaged)
執行 git status
指令時,會發現 Git 將 新增加的檔案 描述成 未追蹤的檔案 (Untracked files)。
可是不對阿…
加入暫存區的檔案叫做 已暫存,那我還沒把檔案加入暫存區,為什麼叫做 未追蹤,不直接叫 未暫存?
在實際開始解釋之前,說明一個可能比較抽象的觀念:
我們說 git add
是把檔案放到暫存區的行為,而這個 暫存區 是真的有這東西,他座落於 .git
資料夾裡面,是一個名叫 index
(索引) 的檔案。
而「索引」到底是不是真的像購物車一樣,下單後會「清空資料」? 其實 「不是」。
在 Git 中,能在加入索引之後,又移出索引的資料,只有 還沒 commit 過的資料 才能做到。
否則,只要 commit 過的檔案,資料永遠會紀錄在 索引 裡面。
檔案進了 Git 就跟得罪方丈一樣,想走沒那麼容易!- 高見龍 (龍哥)《為你自己學 Git》
如果你還沒因為 暫存區 又叫 索引 這件事混淆的話,那我們繼續看下去:
# 未追蹤 (Untracked) 、追蹤 (Tracked) 的定義
- 未追蹤的檔案 (Untracked files):所有 不在索引 的檔案。
- 已追蹤的檔案 (Tracked files):所有 存在於索引 的檔案。
同時,已追蹤 的檔案,可以再區分成 未暫存 與 暫存:
# 未暫存 (Unstaged)、暫存 (Staged) 的定義
- 未暫存的檔案 (Unstaged files):索引的內容 與 工作目錄的內容 不一致 的檔案
- 已暫存的檔案 (Staged files):索引的內容 與 作目錄的內容 一致 的檔案
了解定義之後,我們可以回頭來看工作目錄中,可能會有的檔案狀態:
# 工作目錄可能會出現的檔案狀態整理
在工作目錄中操作檔案,以及執行會更動索引資料的指令 (註 1) 時,都會使檔案狀態發生變化。
下文整理 (註 2) 一下我們在開發與版控時,工作目錄的檔案可能會出現的狀態,這裡更動索引資料的指令,以最常使用的 git add
為例:
- 執行
git add
之前:
- 新增檔案 (尚未列入追蹤的檔案) :未追蹤
- 執行
git add
之後:
- 新增檔案 (已經加入索引的檔案) :已追蹤 / 暫存
- 修改檔案 (已經加入索引的檔案) :已追蹤 / 暫存
- 刪除檔案 (已經加入索引的檔案) :已追蹤 / 暫存
- 執行
git commit
之後又進行異動:
- 修改檔案 (尚未加入索引的檔案) :已追蹤 / 未暫存
- 刪除檔案 (尚未加入索引的檔案) :已追蹤 / 未暫存
用上面列的這三種區域來看的話,當檔案被 commit 過後,編輯這些檔案再 commit 一版的行為,就是不停的讓檔案在 第三區 與 第二區 的狀態不斷循環。
註 1. 在 Git 中,並不只有
git add
與git commit
兩個指令會影響到檔案狀態,舉凡一切會去異動索引資料的指令,都會影響檔案在 Git 中的狀態,例如reset
、rebase
等。
註 2. 原始資料整理自保哥的文章。
# 常見問題
# 「未追蹤」的檔案算不算「未暫存」的檔案?
廣義來說,算。
記得 Fork GUI 介面中,工作目錄剛新增的那些 未追蹤檔案 出現的位置在哪嗎?
沒錯,竟然是未暫存區 (Unstaged)!
如果你已經忘記了,我附個圖:
(p.s. 朋友希望 Fork 的畫面能跟背景色有對比,預計之後都會以深色系來截圖)
再列一次兩個名詞的定義:
- 「未追蹤」檔案:尚未紀錄到索引 的檔案。
- 「未暫存」檔案:索引 與 工作目錄 資料「
不一致
」 的檔案。
有了定義,我們就可以來證明這兩者是不是相同的意思。
試證明: 「未追蹤」 檔案等於 「未暫存」 檔案:
- 因為 「未追蹤」 檔案是 「尚未紀錄到索引」 的檔案,所以 「索引」 不會有 「未追蹤」 的資料。
- 雖然 「索引」 沒有 「未追蹤」 檔案,但如果出現 「未追蹤」 的檔案,表示工作目錄有檔案。
- 由第二點推論出 「未追蹤」 的檔案在 「索引與工作目錄」 兩個位置的資料 「不一致」 。
- 由於 「索引與工作目錄」 記錄的資料 「不一致」 的檔案,稱為 「未暫存」 的檔案。
得證: 「未追蹤」 檔案等於 「未暫存」 檔案。
# 總結
我們在使用 Git 版控,都是持續更改檔案狀態的行為,了解 Git 對檔案狀態的分類,可以在未來面對不同情境時,知道下一步該如何操作,不會手忙腳亂。
如果因為這篇文章的各種狀態,以及看完證明題後搞得頭暈腦脹, 然後不想再跟我這種數學系的人說話 ,在初學 Git 的階段,先記得一件事情就好: