3

我知道git reset myFile.txt取消跟踪 myFile.txt。

如果我在 git repo 中创建一个文件 myFile.txt,然后调用git diff,我可以看到 myFile.txt 被列为差异。添加后,我看不到 myFile.txt 有什么不同。这是意料之中的,因为我现在正在跟踪文件。

但是,如果我使用git reset myFile.txtuntrack myFile.txt,我看不到 myFile.txt 在git diff. 这是为什么?不git diff应该向我展示我未跟踪的更改吗?

4

2 回答 2

5

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 的各个阶段之间移动内容。

于 2013-06-23T10:34:39.997 回答
1

git diff对 repo 索引中的文件运行差异。如果该文件尚未被跟踪,则它不在索引中,因此您不会在git diff.

运行时git add,git 会将文件添加到索引中。这意味着后续git diff将在输出中显示该文件。

要查看未跟踪的文件,请git status改为运行。

于 2013-06-22T20:13:27.510 回答