Git
章節 ▾ 第二版

7.2 Git 工具 - 互動式暫存

互動式暫存

在本節中,您將了解一些互動式的 Git 命令,它們可以幫助您製作提交,使其僅包含特定的組合和檔案部分。如果您大量修改了許多檔案,然後決定將這些變更分割成幾個重點明確的提交,而不是一個大型混亂的提交,這些工具會很有用。這樣,您可以確保您的提交在邏輯上是獨立的變更集,並且可以讓與您合作的開發人員輕鬆審查。

如果您使用 -i--interactive 選項執行 git add,Git 會進入互動式 shell 模式,顯示如下內容

$ git add -i
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now>

您可以看到,此命令顯示的暫存區視圖與您可能習慣的視圖大不相同 — 基本上,它與 git status 提供的資訊相同,但更簡潔且資訊更豐富。它會在左側列出您已暫存的變更,右側列出未暫存的變更。

接著是「命令」區段,您可以在其中執行許多操作,例如暫存和取消暫存檔案、暫存檔案的部分內容、新增未追蹤的檔案,以及顯示已暫存內容的差異。

暫存與取消暫存檔案

如果您在 What now> 提示符號處輸入 u2(代表更新),系統會提示您要暫存哪些檔案

What now> u
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Update>>

要暫存 TODOindex.html 檔案,您可以輸入數字

Update>> 1,2
           staged     unstaged path
* 1:    unchanged        +0/-1 TODO
* 2:    unchanged        +1/-1 index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Update>>

每個檔案旁邊的 * 表示該檔案已選取要暫存。如果您在 Update>> 提示符號處輸入任何內容後按下 Enter,Git 會選取任何已選取的內容並為您暫存

Update>>
updated 2 paths

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> s
           staged     unstaged path
  1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

現在您可以看到 TODOindex.html 檔案已暫存,而 simplegit.rb 檔案仍未暫存。如果您此時想要取消暫存 TODO 檔案,請使用 r3(代表還原)選項

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Revert>> 1
           staged     unstaged path
* 1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb
Revert>> [enter]
reverted one path

再次查看您的 Git 狀態,您可以看到您已取消暫存 TODO 檔案

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> s
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

要查看您已暫存內容的差異,您可以使用 d6(代表差異)命令。它會顯示您的已暫存檔案清單,您可以選取想要查看已暫存差異的檔案。這很像在命令列上指定 git diff --cached

*** Commands ***
  1: [s]tatus     2: [u]pdate      3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff        7: [q]uit       8: [h]elp
What now> d
           staged     unstaged path
  1:        +1/-1      nothing index.html
Review diff>> 1
diff --git a/index.html b/index.html
index 4d07108..4335f49 100644
--- a/index.html
+++ b/index.html
@@ -16,7 +16,7 @@ Date Finder

 <p id="out">...</p>

-<div id="footer">contact : support@github.com</div>
+<div id="footer">contact : email.support@github.com</div>

 <script type="text/javascript">

使用這些基本命令,您可以使用互動式新增模式更輕鬆地處理您的暫存區。

暫存修補

Git 也可以暫存檔案的某些部分,而不是全部。例如,如果您對您的 simplegit.rb 檔案做了兩項變更,而您只想暫存其中一項,另一項則不暫存,在 Git 中這非常容易做到。在上一節說明的相同互動式提示中,輸入 p5(代表 patch)。Git 會詢問您要部分暫存哪些檔案;然後,針對所選檔案的每個區段,它會顯示檔案差異的 hunk,並詢問您是否要逐一暫存它們

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index dd5ecc4..57399e0 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -22,7 +22,7 @@ class SimpleGit
   end

   def log(treeish = 'master')
-    command("git log -n 25 #{treeish}")
+    command("git log -n 30 #{treeish}")
   end

   def blame(path)
Stage this hunk [y,n,a,d,/,j,J,g,e,?]?

此時您有很多選項。輸入 ? 會顯示您可以執行的操作列表

Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ?
y - stage this hunk
n - do not stage this hunk
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

一般來說,如果您想暫存每個 hunk,您會輸入 yn,但有時暫存某些檔案中的所有 hunk,或是先跳過 hunk 的決定稍後再處理也很有幫助。如果您暫存檔案的一部分,而將另一部分保持未暫存狀態,您的狀態輸出看起來會像這樣

What now> 1
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:        +1/-1      nothing index.html
  3:        +1/-1        +4/-0 lib/simplegit.rb

simplegit.rb 檔案的狀態很有趣。它顯示您有幾行已暫存,而有幾行未暫存。您已部分暫存這個檔案。此時,您可以退出互動式加入指令碼,並執行 git commit 以提交部分暫存的檔案。

您也不需要在互動式加入模式下執行部分檔案暫存 — 您可以在命令列上使用 git add -pgit add --patch 來啟動相同的指令碼。

此外,您可以使用 patch 模式,透過 git reset --patch 命令來部分重設檔案,透過 git checkout --patch 命令來檢查檔案的某些部分,以及透過 git stash save --patch 命令來儲存檔案的某些部分。當我們深入探討這些命令的更進階用法時,我們將會更詳細地介紹這些內容。

scroll-to-top