1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | ----- 太棒了!你終於要踏入 Git 最核心也最迷人的功能之一了:「**版本檢視與比較**」。這就像是擁有了一台時光機,讓你能在專案的過去與現在之間自由穿梭,理解每個變動的細節。 你前面跳過它,選擇先熟悉提交、同步等概念,這個學習路徑很不錯!因為沒有穩定的提交,就沒有歷史可以檢視。現在,是時候讓你的 Git 體驗變得更優雅了。 下面給你一個最簡單的學習範例,讓你一步步體驗如何檢視和比較不同版本,然後再「優雅地」回到最新版本。 ----- ## Git 版本檢視與比較:時光機之旅 我們將透過一個簡單的文字檔案來模擬開發過程,並使用 Git 的檢視和比較功能。 ### 準備階段:創建你的練習專案 1. **創建一個新的資料夾作為專案。** ```bash mkdir git_time_machine cd git_time_machine ``` 2. **初始化 Git 倉庫。** ```bash git init ``` 3. **創建第一個檔案並進行第一次提交。** ```bash echo "This is the first line of my document." > document.txt git add document.txt git commit -m "Initial commit: Add document.txt" ``` * 現在你有了第一個版本! ### 第一站:檢視過去的版本 我們來對 `document.txt` 進行一些修改,並進行多次提交,製造一些歷史版本。 1. **修改文件,進行第二次提交。** ```bash echo "This is the second line, added later." >> document.txt git add document.txt git commit -m "Add second line" ``` 2. **再次修改文件,進行第三次提交。** ```bash echo "This is the final line, concluding the document." >> document.txt git add document.txt git commit -m "Add final line" ``` 現在,你的專案有了三個提交。我們來看看這些歷史。 #### 1\. 查看提交歷史:`git log` `git log` 會列出所有的提交歷史,從最新到最舊。 ```bash git log ``` 你會看到類似這樣的輸出(`commit` 後面是一串唯一的 ID,稱為 **SHA-1 雜湊值**): ``` commit a1b2c3d4e5f67890... (HEAD -> master) <- 最新提交,你的 HEAD 和 master 分支指著它 Author: Your Name <[email protected]> Date: Thu Jul 18 15:00:00 2025 +0800 Add final line commit b2c3d4e5f6a1b2c3... <- 第二次提交 Author: Your Name <[email protected]> Date: Thu Jul 18 14:55:00 2025 +0800 Add second line commit c3d4e5f6a1b2c3d4... <- 第一次提交 Author: Your Name <[email protected]> Date: Thu Jul 18 14:50:00 2025 +0800 Initial commit: Add document.txt ``` * 每個 `commit` 行的後面都是一個**唯一的 SHA-1 雜湊值**,它是這個提交的 ID。我們通常只需要記住前 7-8 位即可。 * `HEAD -> master` 表示你當前在 `master` 分支,並且你的工作區指向這個最新的提交。 ### 第二站:檢視與比較版本差異 Git 最強大的地方在於,它可以告訴你**兩個版本之間到底發生了什麼變化**。 #### 1\. 比較當前工作區與最新提交的差異:`git diff` 如果你在文件做了修改,但還沒提交,想看看你做了哪些改動: ```bash echo "A new line that is not yet committed." >> document.txt git diff ``` * `git diff` 會顯示工作目錄中\*\*未暫存(unstaged)\*\*的修改與最新提交之間的差異。 #### 2\. 比較已暫存但未提交的差異:`git diff --staged` 或 `git diff --cached` 如果你已經 `git add` 了一些修改,但還沒 `git commit`: ```bash # 確保上面的新行已經寫入 document.txt git add document.txt git diff --staged # 或 git diff --cached ``` * 這會顯示\*\*已暫存(staged)\*\*的修改與最新提交之間的差異。 #### 3\. 比較任意兩個提交之間的差異:`git diff <commit1_id> <commit2_id>` 這是精華!你可以指定兩個提交的 ID 來比較它們之間的差異。 通常,你可以用 `HEAD` 或分支名來指代最新提交。 * **比較最新提交與前一個提交的差異:** ```bash git diff HEAD~1 HEAD # HEAD~1 表示 HEAD 的前一個提交 # 或者簡寫為 git diff HEAD~1 ``` * 這會顯示你第二次修改 (`Add final line` 的前一個版本) 到最新版本 (`Add final line`) 之間,`document.txt` 發生了什麼變化。 * **比較第一次提交與最新提交的差異:** 先用 `git log` 找到第一次提交的 ID (例如 `c3d4e5f`)。 ```bash git diff c3d4e5f HEAD ``` * 這會顯示從最開始到最新的所有變化。 * **只看某個檔案在兩個提交間的差異:** ```bash git diff c3d4e5f HEAD document.txt ``` `git diff` 的輸出中: * `-` 開頭的行表示在舊版本中有,新版本中被刪除的行。 * `+` 開頭的行表示在舊版本中沒有,新版本中新增的行。 #### 4\. 查看特定提交時的檔案內容:`git show <commit_id>:<file_path>` 如果你想直接看某個歷史提交時,某個檔案的完整內容是什麼: 先用 `git log` 找到你想要查看的提交 ID (例如第二次提交 `b2c3d4e`)。 ```bash git show b2c3d4e:document.txt ``` * 這會將 `document.txt` 在 `b2c3d4e` 這個提交時的內容直接輸出到終端機。 ### 第三站:優雅地回到最新版本 在 `git diff` 和 `git show` 這些操作中,你的工作目錄(你看到和編輯的檔案)並不會改變。你只是在**查看**歷史。所以,當你完成查看後,你的工作目錄和分支指針都還停留在最新的提交。 所以,通常你不需要做任何額外操作來「回到最新版本」,因為你從未離開過。 **但有兩種情況你需要「回到」某個版本:** 1. **暫時切換到某個歷史版本查看或測試 (推薦 `git switch --detach`):** 如果你想回到過去的某個提交,並且在那個點進行一些實驗,但不希望影響你的 `master` 分支歷史。 ```bash git switch --detach b2c3d4e # 假設 b2c3d4e 是第二次提交的 ID ``` * 執行後,你的 `HEAD` 會進入「**分離頭部 (detached HEAD)**」狀態(你之前遇到的情況!)。這表示你的工作區和檔案都變成了 `b2c3d4e` 提交時的樣子。 * 你可以在這裡修改、測試,但如果你在這裡提交,將會在一個沒有分支指向的提交上。 * **優雅地回到最新版本 (從 `detached HEAD` 狀態):** 如果你在 `detached HEAD` 狀態下,完成了查看或測試,想要回到你原來的主分支 (`master`) 的最新狀態: ```bash git switch master ``` * 這會將你的 `HEAD` 和工作目錄切換回 `master` 分支的最新提交。你在分離頭部狀態下沒有提交的變更將會遺失(或被 Git 警告),已提交的則會變成「孤兒提交」(不被任何分支引用)。 2. **完全撤銷歷史,回到某個舊版本,並丟棄之後的提交 (謹慎使用 `git reset --hard`):** 如果你真的想要抹除從某個歷史提交之後的所有變更,讓專案回到那個舊的狀態。 **警告:這會丟失數據,請務必確定你不再需要那些被重置掉的提交。** ```bash git reset --hard b2c3d4e # 假設 b2c3d4e 是你想回到的舊版本 ID ``` * 這會將 `HEAD`、`master` 分支指針、暫存區和工作目錄全部重置到 `b2c3d4e` 這個提交時的狀態。該提交之後的所有歷史將會從 `master` 分支上消失。 * **優雅地回到最新版本 (從 `git reset --hard` 回去):** 一旦 `git reset --hard` 執行了,要回到被丟棄的最新版本就比較麻煩了,需要用到 `git reflog` 來找回那些「看似消失」的提交。 ```bash git reflog # 找到你之前最新提交的 ID git reset --hard <你找到的最新提交ID> ``` * **總結:** 由於 `git reset --hard` 的破壞性,**不建議在日常檢視和比較時使用它**。它應該只在確定需要重寫歷史時才使用。 ### 總結 * **檢視歷史:** `git log` * **比較差異:** * 未暫存:`git diff` * 已暫存:`git diff --staged` * 任意兩提交:`git diff <commit_id1> <commit_id2>` * **查看歷史檔案內容:** `git show <commit_id>:<file_path>` * **安全地時光穿梭 (檢視/測試):** 1. `git switch --detach <commit_id>` 2. 看完後 `git switch master` 回到主分支最新狀態 現在,你可以放心地在你的 Git 專案中穿梭時光了!試著在你自己的網站專案裡,對某些文件進行小修改,提交,再用 `git diff` 看看差異,你會對 Git 的版本控制能力有更直觀的感受! |
Direct link: https://paste.plurk.com/show/UfCippWmmEhsYKvzY6dj