2012-07-03 17 views
9

我使用git checkout --<dir_name(or)file_name>来放弃特定目录或文件中的所有更改。每当我这样做时,GIT都会从存储库中检出目录(或)文件。- git checkout中的干运行选项

有没有一种方法,我可以告诉GIT?“不会覆盖的变化,只是告诉我会发生什么。

类似git clean -n(或)git clean --dry-run

UPDATE: 我执行之前,git checkout --src/,我想看看有哪些会被覆盖的文件。我知道我们可以使用git status src/。但是,git checkout -n --src/不是很好吗?对用户没有太多的命令更改。

+0

也许我很困惑,但你不只是要求你的工作树和索引之间的差异?那些用'git diff'显示。 –

+0

@TilmanVogel:如您所知,'git clean'命令将删除未跟踪的文件。但'git clean -n'不会删除文件,它只是告诉文件将被删除。我只是想知道,在git checkout命令中是否有这样的选项。谢谢。 –

+0

好的,那么看看'git help checkout'很容易回答为“否”。我认为原因是'git status'和'git diff'一起给出了所有相应的信息。我也喜欢'git citool'。当然,这个故事在使用'git checkout'时不同于索引。 –

回答

3

您可以运行

$ git checkout --patch -- <files> 

,它会要求每个差你是否要“退房”这种差别。如果你对每个提示都说不,那么它就会保持不变。

+0

不错。这几乎是我想要的。谢谢。 –

+0

但我仍然觉得,如果'git checkout'具有'-n'选项,就像'git clean'一样,这可能会很棒。给我们一个文件名列表,而不是内容。不管怎么说,还是要谢谢你。 –

1

不知道,但作为一个工作,你可不git stash -u然后git apply然后git checkout

如果你不满意,你总是可以回到藏匿处。

5

Git checkout命令没有dry-run(或类似)选项。但是,您可以使用Git的ls-files命令来查看其工作目录中的文件从HEAD不同:

git ls-files -dm -- src/ 

这将列出已被删除或修改的所有文件,将通常由checkout被覆盖的文件。

另一种选择是使用的Git diff命令:

git diff --name-only HEAD -- src/ 

此列出了从头部不同,将在checkout替换所有文件。

如果是这种东西,会经常做,你可能希望创建一个alias

git config --global alias.lco "diff --name-only HEAD" 

然后你可以使用:

git lco -- src/ 
+0

谢谢丹。这非常有用。我做了upvote :-) –

0

如果你想避免交互(一拉“对每个提示说不”),使用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 diffgit 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 applygit add -p时。

1

对于任何命令,您都希望使用干运行选项,而不管假设“您不需要用于结帐的干运行,因为您可以通过其他方式获取差异列表”。

您不想通过干运行选项来获取差异列表,您需要进行干运行以验证“按下输入时会发生什么情况?”。在你真正做到之前。它们是有区别的。您正在测试程序的实际/确切行为,如果您所做的只是阅读手册,可能会有些不明确之处。

我有一个奇怪的项目,其中回购基于'/'。所以,有一个'/.git'目录和'/.gitignore'和'/.gitmodules'文件。 /.gitignore和/。gitmodules文件在回购中被跟踪,这是一个问题,因为即使开发人员用户有权编辑文件,他们仍然没有权限删除并重新创建文件,因为不可以和可以',对'/'本身有写权限。如果git编辑的文件就地没有问题,但git删除并替换,因为用户得到一个错误,git无法取消链接文件。在发展变化给我们回购的配置,以及一些方向为开发的过程中遵循在未来可以解决这一问题,一路上我想知道会这个命令做到:

git checkout master -- /.git*

等可能的变化像

git checkout master -- '/.git*'

等,改变壳通配符和/或查看的git本身可能会将最终的文件规范值。如果我从shell中转义'*',git会扩展一个'*',还是将它视为文字?如果扩展它,它会包含'/.git/'目录吗?如果它扩展它,是否有一些我可以使用的正则表达式语法意味着'任何单一非空字符'就像一个'。'。在正则表达式或'?'在外壳上? etc等

我不想知道哪些文件是不同的,我想测试一下git的确切行为,找到一个不寻常的命令或命令集的最佳/最简单的版本。

为此,您真的想要一个干运行选项。我已经知道哪些文件是不同的。在这种情况下,MANY文件会有所不同,我不想要其中的任何文件。我只想要/.gitignore和/.gitmodules,而没有别的。

在这种情况下,我知道我可以通过在命令行中明确指定它们来做到这一点。

git checkout master -- /.gitignore /.gitmodules

但我想看看是否有更短的通配语法,将自动获得他们两个,但理想情况下,不包括/.git目录。理想的情况下,我想弄清楚我可以摆脱的最简单的形式。我知道我可以使用shell来做一些特殊的扩展,但是如果像'/ git *'这样的东西可以工作,我宁愿使用'/ git {i,m} *'

这个特殊的任务很小,有几个简单的答案。请不要告诉我在没有“git checkout --dry-run”的情况下解决这个问题的方法,或者告诉我做一个回购有多愚蠢,我也知道。我已经知道几种方法来完成我的直接工作。那不是重点。它可能很容易涉及更多的文件或更复杂的匹配模式,以至于明确列出文件并不方便,或者它可能是一些完全不同类型的问题。

关键是,一般来说,适用于任何地方的任何命令,包括git checkout,总有一个用于测试程序本身行为的干运行选项。阅读手册或--help不能回答以空运回答的问题。