如果重置它,为什么我不能在git diff中看到文件?

时间:2013-06-22 20:10:03

标签: git

我知道git reset myFile.txt取消了myFile.txt。

如果我在git repo中创建文件myFile.txt,然后调用git diff,我可以看到myFile.txt被列为差异。我添加它后,我看不到myFile.txt的区别。这是预期的,因为我现在正在跟踪文件。

但是,如果我使用git reset myFile.txt取消跟踪myFile.txt,我看不到git diff中列出的myFile.txt。这是为什么?是不是git diff应该向我展示我未经修改的变化?

2 个答案:

答案 0 :(得分:3)

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正在将工作树与索引进行比较,并且当我们执行上一个git add时,我们将“Hello again”行添加到索引中。这不会显示为提交而进行的更改。为此,我们回到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's Git Cheatsheet,它向您展示了命令如何在git中的各个阶段之间移动内容。

答案 1 :(得分:1)

git diff对repo索引中的文件运行diff。如果尚未跟踪该文件,则该文件不在索引中,因此您不会在git diff的输出中看到它。

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

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