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` 提供的信息基本一致,但更加简洁、信息丰富。它列出了您已暂存的变更(左侧)和未暂存的变更(右侧)。

之后是“Commands”部分,允许您执行许多操作,例如暂存和取消暂存文件、暂存文件的部分内容、添加未跟踪文件以及显示已暂存内容的差异。

暂存和取消暂存文件

如果您在 `What now>` 提示符下键入 `u` 或 `2`(用于更新),系统将提示您输入要暂存的文件

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

要暂存 `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>>` 提示符下不输入任何内容并按 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

现在,您可以看到 `TODO` 和 `index.html` 文件已暂存,`simplegit.rb` 文件仍然未暂存。如果您想此时取消暂存 `TODO` 文件,您可以使用 `r` 或 `3`(用于还原)选项

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

要查看已暂存内容的差异,您可以使用 `d` 或 `6`(用于差异)命令。它将显示已暂存文件的列表,您可以选择要查看已暂存差异的文件。这与在命令行上指定 `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 : [email protected]</div>
+<div id="footer">contact : [email protected]</div>

 <script type="text/javascript">

使用这些基本命令,您可以使用交互式添加模式更轻松地处理暂存区域。

暂存补丁

Git 也可以暂存文件的特定部分,而不是其他部分。例如,如果您在 `simplegit.rb` 文件中进行了两次修改,并且想要暂存其中一个,而不是另一个,在 Git 中执行此操作非常简单。从上一节中介绍的同一个交互式提示符中,键入 `p` 或 `5`(用于补丁)。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` 来启动同一个脚本。

此外,您可以使用补丁模式来部分重置文件,方法是使用git reset --patch命令,检查文件的部分内容,方法是使用git checkout --patch命令,以及将文件的部分内容存入暂存区,方法是使用git stash save --patch命令。 当我们开始使用这些命令的更高级功能时,我们将详细介绍这些功能。

scroll-to-top