Git提供了很多腳本來輔助某些命令行任務。這里,你將看到一些交互式命令,它們幫助你方便地構建只包含特定組合和部分文件的提交。在你修改了一大批文件然后決定將這些變更分布在幾個各有側重的提交而不是單個又大又亂的提交時,這些工具非常有用。用這種方法,你可以確保你的提交在邏輯上劃分為相應的變更集,以便于供和你一起工作的開發者審閱。如果你運行git add時加上-i或者--interactive選項,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: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
~~~
你會看到這個命令以一個完全不同的視圖顯示了你的暫存區——主要是你通過git status得到的那些信息但是稍微簡潔但信息更加豐富一些。它在左側列出了你暫存的變更,在右側列出了未被暫存的變更。
在這之后是一個命令區。這里你可以做很多事情,包括暫存文件,撤回文件,暫存部分文件,加入未被追蹤的文件,查看暫存文件的差別。
## 暫存和撤回文件
如果你在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>>
~~~
如果想暫存TODO和index.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>>提示后直接敲入回車,Git會替你把所有選中的內容暫存:
~~~
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和index.html文件被暫存了同時simplegit.rb文件仍然未被暫存。如果這時你想要撤回TODO文件,就使用3或者r(代表revert,恢復)選項:
~~~
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
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(表示diff)命令。它會顯示你暫存文件的列表,你可以選擇其中的幾個,顯示其被暫存的差異。這跟你在命令行下指定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">
~~~
通過這些基本命令,你可以使用交互式增加模式更加方便地處理暫存區。
## 暫存補丁
只讓Git暫存文件的某些部分而忽略其他也是有可能的。例如,你對simplegit.rb文件作了兩處修改但是只想暫存其中一個而忽略另一個,在Git中實現這一點非常容易。在交互式的提示符下,輸入5或者p(表示patch,補丁)。Git會詢問哪些文件你希望部分暫存;然后對于被選中文件的每一節,他會逐個顯示文件的差異區塊并詢問你是否希望暫存他們:
~~~
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
~~~
如果你想暫存各個區塊,通常你會輸入y或者n,但是暫存特定文件里的全部區塊或者暫時跳過對一個區塊的處理同樣也很有用。如果你暫存了文件的一個部分而保留另外一個部分不被暫存,你的狀態輸出看起來會是這樣:
~~~
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 -p或者git add --patch來啟動同樣的腳本。
- 1. 起步
- 1.1 關于版本控制
- 1.2 Git 簡史
- 1.3 Git 基礎
- 1.4 安裝 Git
- 1.5 初次運行 Git 前的配置
- 1.6 獲取幫助
- 1.7 小結
- 2. Git基礎
- 2.1 取得項目的 Git 倉庫
- 2.2 記錄每次更新到倉庫
- 2.3 查看提交歷史
- 2.4 撤消操作
- 2.5 遠程倉庫的使用
- 2.6 打標簽
- 2.7 技巧和竅門
- 2.8 小結
- 3. Git分支
- 3.1 何謂分支
- 3.2 分支的新建與合并
- 3.3 分支的管理
- 3.4 利用分支進行開發的工作流程
- 3.5 遠程分支
- 3.6 分支的衍合
- 3.7 小結
- 4. 服務器上的Git
- 4.1 協議
- 4.2 在服務器上部署 Git
- 4.3 生成 SSH 公鑰
- 4.4 架設服務器
- 4.5 公共訪問
- 4.6 GitWeb
- 4.7 Gitosis
- 4.8 Gitolite
- 4.9 Git 守護進程
- 4.10 Git 托管服務
- 4.11 小結
- 5. 分布式Git
- 5.1 分布式工作流程
- 5.2 為項目作貢獻
- 5.3 項目的管理
- 5.4 小結
- 6. Git工具
- 6.1 修訂版本(Revision)選擇
- 6.2 交互式暫存
- 6.3 儲藏(Stashing)
- 6.4 重寫歷史
- 6.5 使用 Git 調試
- 6.6 子模塊
- 6.7 子樹合并
- 6.8 總結
- 7. 自定義Git
- 7.1 配置 Git
- 7.2 Git屬性
- 7.3 Git掛鉤
- 7.4 Git 強制策略實例
- 7.5 總結
- 8. Git與其他系統
- 8.1 Git 與 Subversion
- 8.2 遷移到 Git
- 8.3 總結
- 9. Git 內部原理
- 9.2 Git 對象
- 9.3 Git References
- 9.4 Packfiles
- 9.5 The Refspec
- 9.6 傳輸協議
- 9.7 維護及數據恢復
- 9.8 總結
- 9.1 底層命令 (Plumbing) 和高層命令 (Porcelain)