--git签出中的干运行选项

--git签出中的干运行选项,git,git-checkout,Git,Git Checkout,我使用git checkout--放弃特定目录或文件中的所有更改。每当我这样做时,GIT都会从存储库中签出目录(或)文件 有没有办法告诉GIT?“不要覆盖更改,告诉我会发生什么。” 类似于git clean-n(或)git clean-dry run 更新: 在执行,git checkout--src/之前,我想看看哪些文件将被覆盖。我知道我们可以使用git status src/。但是,拥有git checkout-n--src/不是很好吗?用户的命令更改不多。不确定,但作为一种解决方法,您是

我使用
git checkout--
放弃特定目录或文件中的所有更改。每当我这样做时,GIT都会从存储库中签出目录(或)文件

有没有办法告诉GIT?“不要覆盖更改,告诉我会发生什么。

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

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

不确定,但作为一种解决方法,您是否可以
git stash-u
然后
git apply
然后
git checkout

如果你不开心,你可以随时回到藏身处。

你可以跑步

$ git checkout --patch -- <files>
$git签出--修补程序--
它会询问每个差异,你是否想“检验”这个差异。如果您对每个提示符都说“否”,则它将保持不变。

Git命令没有“干运行”(或类似)选项。但是,您可以使用Git命令查看哪些工作目录文件不同于
HEAD

git ls-files -dm -- src/
这将列出所有已删除或修改的文件,这些文件通常会被
签出覆盖

另一个选项是使用Git命令:

此列表列出了与HEAD不同的所有文件,这些文件将在
签出时被替换

如果这是经常要做的事情,您可能需要创建一个:

然后您可以使用:

git lco -- src/

如果您想避免交互(对每个提示说“不”),请使用
git diff
。如果您想得到问题的确切答案,请使用
git diff-R
。如果只需要文件名,请使用
git diff--name only

如果没有
-R
标志,
git diff
将以补丁格式报告工作树和索引之间的所有差异,即发布
git show
时看到的格式。
-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>
你知道吗?我不太喜欢第二次。它的实现是有缺陷的。它正在打破测试。我不想分享它。尽管如此,我还是希望保留“secondcommit”提交消息,因为这确实很难键入。我可以用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
组合在一起时,您希望任何命令都有一个干运行选项,而不必考虑“您不需要干运行来进行签出,因为您可以通过其他方式获得差异列表”的想法

您不希望使用“试运行”选项来获取差异列表,而是希望在实际操作之前,通过试运行来验证“当我按enter键时会发生什么情况”。这是有区别的。您正在测试程序的实际/精确行为,如果您只是阅读了手册,那么可能会出现一些歧义

我有一个奇怪的项目,回购协议就在“/”中。因此,有一个“/.git”目录和“/.gitignore”和“/.gitmodules”文件。/.gitignore和/.gitmodules文件在repo中被跟踪,这是一个问题,因为即使开发人员用户有权编辑该文件,他们仍然没有权限让git删除和重新创建该文件,因为开发人员用户没有也不能对“/”本身拥有写权限。如果git在适当的位置编辑了文件,就不会有问题,但是git会删除并替换文件,因为用户会收到一个错误,git无法取消文件链接。在对我们的repo配置进行更改的过程中,以及开发人员在将来消除此问题时遵循的一些方向,我想知道这个命令将做什么:

git签出主机--/.git*

以及其他可能的变化,如

git签出主机--'/.git*'

和其他人一样,改变shell globbing和/或查看git本身如何解释最终的filespec值。如果我从shell中转义一个“*”,git会扩展一个“*”,还是将它视为一个文本?如果扩展它,它会包括“/.git/”目录吗?如果它扩展它,我是否可以使用一些正则表达式语法来表示“任何单个非空字符”,如正则表达式中的“.”或shell globbing中的“?”?等等

我不想知道什么文件是不同的,我想测试git的确切行为,以找到一个不寻常命令或一组命令的最佳/最简单版本

为此,您真的需要一个试运行选项。我已经知道什么了
git diff -- <file>
git add .
git commit -m "Second commit"
echo "even newer line">file
git add .
git commit -m "Third commit"
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'