git reset
并不总是取消跟踪文件。只有在之前没有被跟踪的情况下才会这样做。git diff
仅向您显示未分级的更改。如果文件未被跟踪,git 会忽略它,除非在状态输出中,它让你知道有一个你可能想要跟踪的文件。让我们从一个干净的存储库开始:
$ git init practice
$ cd practice
现在,让我们添加一个文件:
$ echo "Hello World" > hello.txt
此时,git status
表示文件未跟踪:
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# hello.txt
nothing added to commit but untracked files present (use "git add" to track)
所以在这里做一个git diff
不会向我们展示什么,因为 git 现在基本上忽略了该文件:
$ git diff
现在,让我们添加hello.txt
到索引中:
$ git add hello.txt
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: hello.txt
#
git diff
仍然没有向我们展示:
$ git diff
这样做的原因是因为git diff
会告诉你索引和工作树之间的区别。现在我们已经添加hello.txt
到索引中,工作树匹配,所以没有什么git diff
可显示的。
如果您想查看提交的内容,请尝试git diff --cached
:
$ git diff --cached
diff --git a/hello.txt b/hello.txt
new file mode 100644
index 0000000..557db03
--- /dev/null
+++ b/hello.txt
@@ -0,0 +1 @@
+Hello World
仅供参考,以下是--cached
命令行选项的帮助:
此表单用于查看您为下一次提交相对于命名的<commit>
. 通常,您希望与最新提交进行比较,因此如果您不提供<commit>
,则默认为HEAD
. 如果HEAD
不存在(例如未出生的分支)并且<commit>
未给出,则显示所有阶段性更改。
--staged
是的同义词--cached
。
当您此时进行重置时,您不仅仅是取消暂存文件的内容,git 会返回将文件视为未跟踪:
$ git reset hello.txt
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# hello.txt
nothing added to commit but untracked files present (use "git add" to track)
结果,git diff
什么都不会给你看。即使您执行了git commit -a
,该文件也不会被提交,因为它未被跟踪。
一旦文件被跟踪,故事就会发生变化。所以让我们添加它并提交它:
$ git add hello.txt
$ git commit -m "Initial commit."
[master (root-commit) 67cb14e] Initial commit.
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
$ git status
# On branch master
nothing to commit, working directory clean
现在,让我们添加更多文本:
$ echo "Hello again" >> hello.txt
$ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: hello.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
的输出发生git status
了变化。我们现在看到hello.txt
的是修改过的,而之前它是未跟踪的。现在git diff
可以工作,因为该文件存在于索引中并且正在被跟踪。索引版本是您已暂存的任何内容,或者它与最后一次提交 ( HEAD
) 匹配,如果您没有暂存任何内容:
$ git diff
diff --git a/hello.txt b/hello.txt
index 557db03..49e9db5 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,2 @@
Hello World
+Hello again
让我们暂存它并查看差异:
$ git add hello.txt
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: hello.txt
#
$ git diff
现在我们又看到没有区别,因为索引中的内容与工作树匹配。让我们重置:$ git reset hello.txt 重置后未分级的更改:M hello.txt
现在我们可以再次看到变化:
$ git diff
diff --git a/hello.txt b/hello.txt
index 557db03..49e9db5 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,2 @@
Hello World
+Hello again
Git 并没有在此处取消跟踪文件,它只是重置了索引的内容。该文件仍在跟踪中。让我们添加hello.txt
到索引并进行更改,以展示与索引进行比较的最后一部分:
$ git add hello.txt
$ echo "One final change" >> hello.txt
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: hello.txt
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: hello.txt
#
所以现在我们看到hello.txt
有一些更改已准备好提交,而有些则没有:
$ git diff
diff --git a/hello.txt b/hello.txt
index 49e9db5..97849b8 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1,2 +1,3 @@
Hello World
Hello again
+One final change
请注意,它仅显示添加了“最后一次更改”行。那是因为git diff
正在将工作树与索引进行比较,并且我们在执行最后一个时将“Hello again”行添加到索引中git add
。但是,这并没有显示为提交暂存了哪些更改。为此,我们回到git diff --cached
:
$ git diff --cached
diff --git a/hello.txt b/hello.txt
index 557db03..49e9db5 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,2 @@
Hello World
+Hello again
此时,让我们将索引重置并恢复为 中的版本HEAD
:
$ git reset hello.txt
由于我们不再进行任何更改,因此git diff --cached
返回干净:
$ git diff --cached
并将git diff
显示这两个变化:
$ git diff
diff --git a/hello.txt b/hello.txt
index 557db03..97849b8 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,3 @@
Hello World
+Hello again
+One final change
希望这可以帮助您了解更改如何在工作树和索引之间来回传输,未跟踪的文件基本上被忽略,以及如何查看已暂存的更改。我见过的最好的可视化是NDP Software 的 Git Cheatsheet,它向您展示了命令如何在 git 的各个阶段之间移动内容。