git 添加所有具有非空差异的文件
git add all files with nonempty diff
是否有 git
命令添加所有 git diff <file>
的输出不为空的已修改文件?*
(*使用自动删除文件某些部分的工具可能会发生修改但为空的差异)
(*Modified but empty diff can happen by using tools that strip out certain parts of the files before)
不,不能。如果您删除了跟踪文件的一部分,这将显示为一个更改块,其中一行以 « - » 符号开头。此外,git 使用快照并始终存储完整文件内容或根本不存储,并使用 SHA1 和对其进行命名和验证。所以,如果你得到一个空的 diff,文件将被强制更改,除非我弄错了。
至于其他人的问题,还是可以用
git add -u
…自动添加已跟踪的更新文件。
EDIT :当使用 git diff <filename>
和单个文件名时,您的文件将与索引进行比较。换句话说,一旦您添加了修改后的文件,它就会脱离常规差异,并在 git status
结果列表中从红色切换为绿色。
检查仍然要添加或不添加的内容很方便。您可以使用
查看您已经添加的内容
git diff --cached
(或--staged,这是一个同义词)。
如果你想“取消添加”一个文件,使用
git reset <filename>
… 在不改变工作树的情况下将索引恢复到 HEAD 指向的提交状态(也就是说,不要 使用 --hard
在这里)。
TL;DR
考虑只使用 git add -u
。你的另一个主要选择是编写你自己的程序,但实际上没有什么意义。
长
以一种不太重要的方式略有错误,但原始问题中缺少一块(至少在这一点上——问题可能会被编辑以解决这个问题)可能误导:
(*Modified but empty diff can happen by using tools that strip out certain parts of the files before)
...之前...什么? :-)
我想我知道你在这里想说什么:你可以有一个 clean filter 来编辑文件,而 Git 从作品中复制文件的内容-树进入索引/暂存区。
请记住,在 Git 中,您工作时实际上有 三个 个文件的活动副本(如果您处于冲突的中间,则更多)合并,尽管这取决于一个人如何计算)。对于每个文件:
有HEAD
版本,只读。您可以git show HEAD:path
查看。它实际上以一种特殊的、仅 Git 的压缩格式存储; git show
必须把它展开。
有索引/暂存区版本。这最初只是文件 HEAD
版本的副本。与 HEAD
版本一样,它采用特殊的、仅 Git 的压缩格式;但与 HEAD
版本不同,您可以 覆盖 此文件。
最后,有一个 Git 本身不关心的版本,但您可能关心:那就是您的工作树中的版本。这是您的计算机可以处理的普通格式,因此它是 read/write,您可以对它做任何您想做的事情。 Git一点都不在乎; Git主要关注索引版本。
因为索引和工作树版本都是可写的,所以您可以更改其中一个或两个。通常,您更改工作树版本,然后告诉 Git 将该工作树版本 复制回索引 。这就是 git add
所做的:从工作树复制到索引中。如果您定义了 clean 过滤器,and/or 如果您设置了行尾更改,git add
将文件复制到索引 同时应用过滤器.
将文件从索引复制到工作树的命令(复数)可以应用 涂抹过滤器 and/or 也可以进行行尾更改。我们每天使用的通常是 git checkout
,它从索引复制到工作树,或者从提交复制到 both 索引 和 工作树,取决于你如何调用 git checkout
.
因为存在涂抹和清洁过滤器,git diff
在将文件的索引版本与同一文件的工作树版本进行比较时必须执行一些特殊操作。 Git 做出的选择是 运行 工作树副本上的干净过滤器。有关详细信息,请参阅 。这里也发生了一些优化:Git 试图知道清理后的工作树文件是否与索引版本匹配,而不必 运行 对文件进行清理过滤器。如果您更改过滤器(包括更改行尾设置),Git 可能会对每个文件的清洁度感到困惑。解决此问题的最简单方法是使用以下两步过程:
- 删除
.git/index
:这将删除所有暂存文件。
- 运行
git reset
(没有其他选项):这会从 HEAD
提交重新创建索引。
当然,这也会清除您所有精心准备的文件。另一种方法是更新工作树中每个文件的修改时间戳(例如,find . -name .git -prune -o -print0 | xargs -0 touch
,但这也有烦人的副作用。Git 需要一个命令(或标记为 git reset
) 使所有缓存数据无效并重新计算,而不删除暂存文件。它没有一个,所以我们都被卡住了。
这让我们回到最初的问题:
Is there a git command to add all modified files for which the output of git diff <file>
is not empty?
是的,有点像:git add
,特别是 git add -u
,is documented this way:
在已有条目匹配的地方更新索引
<路径规范>。这将删除并修改索引条目以匹配
工作树,但不添加新文件。
如果在使用 -u
选项时没有给出 ,则所有跟踪的文件
在整个工作树中更新(旧版本的 Git 用于
限制对当前目录及其子目录的更新)。
我说 "sort of" 因为这也会 删除 工作树中丢失但存在于索引中的文件。至少可以说,它还重新-添加了不显示索引副本和工作树副本之间的任何差异的文件。
当git add
添加完清理过的文件后,Git 更新其在索引中的缓存信息,以便它现在知道该文件是干净的。如果这会将与索引中已有副本相匹配的文件副本添加到索引中,那又如何呢?索引中的文件没有变化,只是现在索引中缓存的时间戳信息是正确的。您为此花费了一些计算时间,但这可能比花费您自己的个人时间要好。
是否有 git
命令添加所有 git diff <file>
的输出不为空的已修改文件?*
(*使用自动删除文件某些部分的工具可能会发生修改但为空的差异)
(*Modified but empty diff can happen by using tools that strip out certain parts of the files before)
不,不能。如果您删除了跟踪文件的一部分,这将显示为一个更改块,其中一行以 « - » 符号开头。此外,git 使用快照并始终存储完整文件内容或根本不存储,并使用 SHA1 和对其进行命名和验证。所以,如果你得到一个空的 diff,文件将被强制更改,除非我弄错了。
至于其他人的问题,还是可以用
git add -u
…自动添加已跟踪的更新文件。
EDIT :当使用 git diff <filename>
和单个文件名时,您的文件将与索引进行比较。换句话说,一旦您添加了修改后的文件,它就会脱离常规差异,并在 git status
结果列表中从红色切换为绿色。
检查仍然要添加或不添加的内容很方便。您可以使用
查看您已经添加的内容git diff --cached
(或--staged,这是一个同义词)。 如果你想“取消添加”一个文件,使用
git reset <filename>
… 在不改变工作树的情况下将索引恢复到 HEAD 指向的提交状态(也就是说,不要 使用 --hard
在这里)。
TL;DR
考虑只使用 git add -u
。你的另一个主要选择是编写你自己的程序,但实际上没有什么意义。
长
(*Modified but empty diff can happen by using tools that strip out certain parts of the files before)
...之前...什么? :-)
我想我知道你在这里想说什么:你可以有一个 clean filter 来编辑文件,而 Git 从作品中复制文件的内容-树进入索引/暂存区。
请记住,在 Git 中,您工作时实际上有 三个 个文件的活动副本(如果您处于冲突的中间,则更多)合并,尽管这取决于一个人如何计算)。对于每个文件:
有
HEAD
版本,只读。您可以git show HEAD:path
查看。它实际上以一种特殊的、仅 Git 的压缩格式存储;git show
必须把它展开。有索引/暂存区版本。这最初只是文件
HEAD
版本的副本。与HEAD
版本一样,它采用特殊的、仅 Git 的压缩格式;但与HEAD
版本不同,您可以 覆盖 此文件。最后,有一个 Git 本身不关心的版本,但您可能关心:那就是您的工作树中的版本。这是您的计算机可以处理的普通格式,因此它是 read/write,您可以对它做任何您想做的事情。 Git一点都不在乎; Git主要关注索引版本。
因为索引和工作树版本都是可写的,所以您可以更改其中一个或两个。通常,您更改工作树版本,然后告诉 Git 将该工作树版本 复制回索引 。这就是 git add
所做的:从工作树复制到索引中。如果您定义了 clean 过滤器,and/or 如果您设置了行尾更改,git add
将文件复制到索引 同时应用过滤器.
将文件从索引复制到工作树的命令(复数)可以应用 涂抹过滤器 and/or 也可以进行行尾更改。我们每天使用的通常是 git checkout
,它从索引复制到工作树,或者从提交复制到 both 索引 和 工作树,取决于你如何调用 git checkout
.
因为存在涂抹和清洁过滤器,git diff
在将文件的索引版本与同一文件的工作树版本进行比较时必须执行一些特殊操作。 Git 做出的选择是 运行 工作树副本上的干净过滤器。有关详细信息,请参阅
- 删除
.git/index
:这将删除所有暂存文件。 - 运行
git reset
(没有其他选项):这会从HEAD
提交重新创建索引。
当然,这也会清除您所有精心准备的文件。另一种方法是更新工作树中每个文件的修改时间戳(例如,find . -name .git -prune -o -print0 | xargs -0 touch
,但这也有烦人的副作用。Git 需要一个命令(或标记为 git reset
) 使所有缓存数据无效并重新计算,而不删除暂存文件。它没有一个,所以我们都被卡住了。
这让我们回到最初的问题:
Is there a git command to add all modified files for which the output of
git diff <file>
is not empty?
是的,有点像:git add
,特别是 git add -u
,is documented this way:
- 在已有条目匹配的地方更新索引
<路径规范>。这将删除并修改索引条目以匹配
工作树,但不添加新文件。
如果在使用 -u
选项时没有给出
我说 "sort of" 因为这也会 删除 工作树中丢失但存在于索引中的文件。至少可以说,它还重新-添加了不显示索引副本和工作树副本之间的任何差异的文件。
当git add
添加完清理过的文件后,Git 更新其在索引中的缓存信息,以便它现在知道该文件是干净的。如果这会将与索引中已有副本相匹配的文件副本添加到索引中,那又如何呢?索引中的文件没有变化,只是现在索引中缓存的时间戳信息是正确的。您为此花费了一些计算时间,但这可能比花费您自己的个人时间要好。