這是我自己常遇到的問題 - 先寫了專案雛型,用 git init 就地建立 Git Repository,在第一次 Commit 放入雛型版本,之後陸續修改加入新的 Commit。

專案第一次上線用 git diff 產出 Compare List,卻發現我無法列舉所有專案檔案。原因是產生 git diff 時需提供 commit-1 commit-2 兩個參數,進而「產生 commit-2 與 commit-1 差異的部分」。由於第一個 Commit 已包含專案雛型的原始檔,被視為一開始已存在的東西,無法當成「差異」輸出。

用實際範例來說明比較清楚。假設我有個專案,先寫好 one.txt 及 two.txt,之後才 git init 建立 Repository,將兩個檔案加入到 Repository 成為首發 Commit。接著再新增 three.txt,建立第二個 Commit:

echo 1 > one.txt
echo 2 > two.txt
git init
git add . && git commit -m "init commit"
echo 3 > three.txt
git add . && git commit -m "add three.txt"

此時 master 分支上只有兩個 Commit Id 可用(下圖[1]),第一個 Commit = 64fd5f9,第二個 Commit = ac8929d (或是用 HEAD 代表),git diff 64fd5f9 HEAD 最多只能得到 Commit ac8929d 加入的 three.txt (下圖[2]):

要怎麼產生包含 one.txt、two.txt、three.txt 三個檔案的 git diff 報告呢?

這裡介紹一個神祕的 Commit Id - 4b825dc642cb6eb9a060e54bf8d69288fbee4904,代表什麼檔案都沒有的虛無狀態,只要用它跟目前的 Commit Id 相比 - git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 HEAD ,便能列出盤古開天以來的所有檔案,包含 one.txt、two.txt、three.txt:

Commit Id 4b825dc642cb6eb9a060e54bf8d69288fbee4904 相當於全空的目錄結構(Tree),故與其相比將得到比較對象的所有項目。

若記不住也沒關係,使用指令 git hash-object -t tree /dev/null 可現場產生:

這樣就能輸出包含第一個 Commit 的 git diff 內容囉~

【參考資料】

Git diff from empty commit Empty trees in Git

Introduce to the empty tree commit hash id to generate git diff report from the very beginning.


Comments

Be the first to post a comment

Post a comment