-
1. 起步
-
2. Git 基础
-
3. Git 分支
-
4. 服务器上的 Git
- 4.1 协议
- 4.2 在服务器上部署 Git
- 4.3 生成 SSH 公钥
- 4.4 架设服务器
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方托管服务
- 4.10 小结
-
5. 分布式 Git
-
A1. 附录 A: Git 在其他环境
- A1.1 图形界面
- A1.2 Visual Studio 中的 Git
- A1.3 Visual Studio Code 中的 Git
- A1.4 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git
- A1.5 Sublime Text 中的 Git
- A1.6 Bash 中的 Git
- A1.7 Zsh 中的 Git
- A1.8 PowerShell 中的 Git
- A1.9 小结
-
A2. 附录 B: 在应用程序中嵌入 Git
-
A3. 附录 C: 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 相同的信息,但更加简洁和信息丰富。它在左侧列出了你已暂存的更改,在右侧列出了未暂存的更改。
接下来是一个“命令”部分,它允许你执行许多操作,例如暂存和取消暂存文件、暂存文件的一部分、添加未跟踪文件以及显示已暂存内容的 diff。
暂存和取消暂存文件
如果在 What now> 提示符处输入 u 或 2 (表示 update),系统会提示你选择要暂存的文件。
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 (表示 revert) 选项。
*** 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
要查看你已暂存内容的 diff,你可以使用 d 或 6 (表示 diff) 命令。它会显示一个已暂存文件的列表,你可以选择你想要查看暂存 diff 的文件。这很类似于在命令行中指定 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">
通过这些基本命令,你可以更轻松地使用交互式 add 模式来处理你的暂存区域。
暂存补丁
Git 也可以暂存文件的某些部分而忽略其余部分。例如,如果你修改了你的 simplegit.rb 文件两次,并只想暂存其中一次修改而不是另一次,在 Git 中这样做非常容易。在上一节解释的交互式提示符下,输入 p 或 5 (表示 patch)。Git 会询问你想要部分暂存哪些文件;然后,对于选定文件的每个部分,它会显示文件 diff 的“hunks”(块),并逐个询问你是否要暂存它们。
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 来决定是否暂存每个 hunk,但一次性暂存某些文件中的所有 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 来提交部分暂存的文件。
你不需要处于交互式 add 模式也可以进行部分文件暂存 — 你可以通过在命令行中使用 git add -p 或 git add --patch 来启动相同的脚本。
此外,你还可以使用 patch 模式来部分重置文件(使用 git reset --patch 命令),部分检出文件(使用 git checkout --patch 命令),以及部分暂存文件(使用 git stash save --patch 命令)。当涉及到这些命令的高级用法时,我们会更详细地介绍它们。