如果你想避免交互(一拉“对每个提示说不”),使用git diff
。如果您想要问题的确切答案,请使用git diff -R
。如果您只需要文件名称,请使用git diff --name-only
。
如果没有-R
标志,git diff
会以补丁格式报告您的工作树和索引之间的所有差异,即您在发出git show <commit>
时看到的格式。 -R
反转输出,告诉你将会发生什么变化被删除,就好像删除本身就是一个补丁。考虑一个例子:
git init /tmp/test && cd /tmp/test
echo "old line">file
git add .
git commit -m "Initial commit"
echo "new line">file
现在发行git diff
没有任何标志。你应该:
$ git diff
diff --git a/file b/file
index 0906fba..86ba82a 100644
--- a/file
+++ b/file
@@ -1 +1 @@
-old line
+new line
坦率地说,我发现,输出很容易解析我从来没有使用-R
标志。如果您经常发出git diff
命令(并且我发现它是我使用的最常用命令之一),则反向输出可能不是必需的。尽管如此,对于这个答案的目的,尝试:
$ git diff -R
git diff -R
diff --git b/file a/file
index 86ba82a..0906fba 100644
--- b/file
+++ a/file
@@ -1 +1 @@
-new line
+old line
这正是输出描述你所追求的:“不覆盖的变化,只是告诉我会发生什么。”
默认情况下,该命令将使用索引来区分整个工作目录。它会显示每个修改文件中的差异。假设你只想看一个文件的效果。这很容易。只需使用你已经在使用相同的双横线命名:
git diff -- <file>
你会发现git diff
是在Git中最有用的,可扩展的命令之一,你可以用它做各种有益的东西。您可以使用它来比较两个提交,两个分支或两个文件。我最近的“最喜欢的疯狂Git操作”是管道git diff
到git apply
。前者产生可理解的补丁。后者适用于他们。当他们结合时重写历史的能力几乎是无限的 - 本地当然,永远不会重写共享历史。考虑另一个例子,在这一点上脱离主题,但严重娱乐(如果你是这样的事情)。从我们的测试库中,上面:
git add .
git commit -m "Second commit"
echo "even newer line">file
git add .
git commit -m "Third commit"
你知道吗?我不喜欢那第二个承诺。它的实现是错误的。它正在破坏测试。我不想分享它。不过,我确实想保留“第二次提交”提交消息,因为这很难输入。我可以用git rebase -i HEAD~2
来重定义它,但是这涉及到打开编辑器,删除提交,编辑另一个和(唉)复制/粘贴。什么是开发者?这个怎么样:
git checkout ":/Initial" ;# get back to the first commit
git diff HEAD ":/Third" | git apply ;# apply the diff between the first and third commit
git add . ;# add the result
git commit -C ":/Second" ;# with second commit's message
git checkout -B master HEAD ;# and replace old 'master'
结果和git rebase
一样。我只是设法避免交互式会话,我不必使用编辑器。这是否过分矫枉过正?可能吧,但它确实很有趣。此外,构建更复杂的用例很容易,特别是当您结合使用git diff
,git apply
和git add -p
时。
也许我很困惑,但你不只是要求你的工作树和索引之间的差异?那些用'git diff'显示。 –
@TilmanVogel:如您所知,'git clean'命令将删除未跟踪的文件。但'git clean -n'不会删除文件,它只是告诉文件将被删除。我只是想知道,在git checkout命令中是否有这样的选项。谢谢。 –
好的,那么看看'git help checkout'很容易回答为“否”。我认为原因是'git status'和'git diff'一起给出了所有相应的信息。我也喜欢'git citool'。当然,这个故事在使用'git checkout'时不同于索引。 –