7.2 Git Tools - Interactive Staging 交互式暫存

Interactive Staging 交互式暫存

Git 自帶一些腳本,方便你在命令行下進行工作。本節會介紹幾個腳本命令,可以讓你一次只暫存文件的一部分(正常的暫存只能存整個文件)。比如有時你文件進行了一些改動,但希望將這些改動做成多個提交,以便讓一次提交只完成一個任務,這樣其他開發者審核起來也比較容易。運行 git add 帶選項 -i 或者 --interactive,Git 會進入一個交互式終端模式:
Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft(制作) your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. If you run git add with the -i or --interactive option, Git goes into an interactive shell mode, displaying something like this:

$ 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: status     2: update      3: revert     4: add untracked
  5: patch      6: diff        7: quit       8: help
What now>

Staging and Unstaging Files 暫存與撤銷暫存

如果在 What now> 提示符后鍵入 2 或 u,腳本就會問你想要暫存哪個文件:

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

輸入相應的數字就可以了:

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>>

前面的 * 意味文件被選中,再次按回車,選中的文件就會被暫存:
The * next to each file means the file is selected to be staged. If you press Enter after typing nothing at the Update>> prompt, Git takes anything selected and stages it for you:

Update>>
updated 2 paths

*** Commands ***
  1: status     2: update      3: revert     4: add untracked
  5: patch      6: diff        7: quit       8: help
What now> 1
           staged     unstaged path
  1:        +0/-1      nothing TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

如果這時想要撤銷對 TODO 文件的暫存,使用 3 或 r(撤消)選項:

What now> 3
           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: status     2: update      3: revert     4: add untracked
  5: patch      6: diff        7: quit       8: help
What now> 1
           staged     unstaged path
  1:    unchanged        +0/-1 TODO
  2:        +1/-1      nothing index.html
  3:    unchanged        +5/-1 lib/simplegit.rb

使用 6 或 d(區別)命令,類似于 git diff --cached

*** Commands ***
  1: status     2: update      3: revert     4: add untracked
  5: patch      6: diff        7: quit       8: help
What now> 6
           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">

如上所述,用腳本后就不用每次都輸入完整的命令了。

Staging Patches 暫存補丁

你也可以只暫存文件的特定部分。例如對 simplegit.rb 文件作了兩處修改,但只想暫存其中的一個。這就是 5 或 p(補丁)的功能:(在Git的提示下,一個一個的處理)
It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type 5 or p (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one:

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

如果你只暫存文件的一部分,狀態可能會是下面這樣:
Generally, you’ll type y or n if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this:

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 就可以提交已經暫存的內容了。
The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run git commit to commit the partially staged files.

在命令行中使用 git add-p--patch 選項,也會啟動同樣的腳本。
You also don’t need to be in interactive add mode to do the partial-file staging – you can start the same script by using git add -p or git add --patch on the command line.

Furthermore, you can use patch mode for partially resetting files with the reset --patch command, for checking out parts of files with the checkout --patch command and for stashing parts of files with the stash save --patch command. We’ll go into more details on each of these as we get to more advanced usages of these commands.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容