代码之家  ›  专栏  ›  技术社区  ›  clstaudt

git添加具有非空diff的所有文件

  •  2
  • clstaudt  · 技术社区  · 6 年前

    有没有 git 命令添加所有已修改的文件 git diff <file> 不是空的吗?*

    (*使用自动删除文件某些部分的工具可能会发生修改但为空的差异)

    2 回复  |  直到 6 年前
        1
  •  2
  •   torek    6 年前

    DR

    考虑使用 git add -u . 你的另一个主要选择是写你自己的程序,但实际上没有什么意义。

    Obsidian's answer 稍微有点错误,以一种不那么重要的方式,但是原始问题中有一个部分缺失(至少在这个点上,问题可能会被编辑以解决这个问题),这可能误导:

    (*使用以前删除文件某些部分的工具可能会发生修改但为空的差异)

    …之前…什么?-)

    我想我知道你想说什么:你可以 清洁过滤器 它在Git将文件内容从工作树复制到索引/临时区域时编辑文件。

    记住,在Git中,实际上 工作时文件的活动副本(如果处于冲突合并的中间,则为更多副本,但这取决于如何计算)。对于每个文件:

    • 这里有 HEAD 版本,只读。你可以 git show HEAD:path 查看它。它实际上是以一种特殊的、仅Git的压缩格式存储的; git show 必须扩大它。

    • 有索引/临时区域版本。这最初只是 文件的版本。就像 版本,它是一种特殊的、仅Git的压缩格式;但与 版本,你可以 覆盖

    • 最后,有一个版本是Git本身不关心的,但您可能会关心的:这是您工作树中的版本。这是你的计算机可以处理的普通格式,所以它是读/写的,你可以做任何你想做的事情。Git一点也不关心;Git主要关心索引版本。

    因为索引和工作树版本都是可写的,所以可以更改其中一个或两个版本。通常,您更改工作树版本,然后告诉Git复制该工作树版本。 回到索引中 . 就是这样 git add 做:从工作树复制到索引中。如果你有 清洁过滤器 已定义,和/或如果设置了行尾更改, Git添加 将文件复制到索引中 应用筛选器时

    将文件从索引复制到工作树的命令(复数)可以应用 污迹过滤器 和/或更改行尾。我们每天工作的习惯是 git checkout 从索引复制到工作树,或从提交到 二者都 索引 工作树,取决于您如何调用 Git结账 .

    因为存在污迹和干净的过滤器, git diff 在比较文件的索引版本和同一文件的工作树版本时,必须做一些特殊的魔术。Git的选择是在工作树副本上运行干净的过滤器。见 my answer to a related question 有关详细信息。这里也进行了一些优化:Git试图知道清理后的工作树文件是否与索引版本匹配,而不必在文件上运行清理过滤器。如果您更改过滤器,这包括更改行尾设置,Git可能会对每个文件的清洁度感到困惑。这个问题最简单的解决方法是使用这两个步骤:

    1. 去除 .git/index :这将删除所有暂存文件。
    2. git reset (没有其他选项):这将从 承诺。

    当然,这也会抹掉所有精心准备的文件。另一种方法是更新工作树中每个文件的修改时间戳(例如, find . -name .git -prune -o -print0 | xargs -0 touch 但这也会产生烦人的副作用。Git需要一个命令(或标志 Git重置 )使所有缓存数据失效并重新计算,而不删除暂存文件。它没有,所以我们都卡住了。


    这让我们回到了最初的问题:

    是否有一个git命令来添加为其输出 git diff <file> 不是空的吗?

    是的,差不多是 Git添加 ,具体来说 git添加-u ,其中 is documented this way :

      仅在索引已有匹配项的位置更新索引 <路径规范>。这将删除并修改索引项以匹配 工作树,但不添加新文件。

      如果在以下情况下未给出路径规范 -u 使用选项,所有跟踪文件 在整个工作树中更新(Git的旧版本用于 将更新限制为当前目录及其子目录)。

    我说“有点”,因为这也是 删除 工作树中缺少但索引中存在的文件。而且,至少可以说, 重新 -添加的文件 不要 显示索引副本和工作树副本之间的任何差异。

    什么时候? Git添加 已经完成添加清理后的文件,Git将在索引中更新其缓存信息,以便现在知道该文件是干净的。如果这将文件的副本添加到索引中,与索引中已经存在的副本相匹配,那么,又是什么呢?索引中的文件不变,只是索引中的缓存时间戳信息现在是正确的。你花了一点计算时间来做这件事,但这可能比花你自己的时间要好。

        2
  •  1
  •   Obsidian mattz608    6 年前

    (*使用以前删除文件某些部分的工具可能会发生修改但为空的差异)

    不可以。如果删除跟踪文件的一部分,这将显示为一个更改块,其中的行以“~”符号开头。此外,Git使用快照并始终存储完整的文件内容,或者根本不存储完整的文件内容,并使用sha1总和命名和验证它。所以,如果您得到一个空的diff,那么文件将被强制保持不变,除非我出错了。

    至于剩下的问题,你仍然可以使用

    git add -u
    

    自动添加已跟踪的更新文件。

    编辑 :使用时 git diff <filename> 如果只有一个文件名,则会将文件与索引进行比较。换句话说,一旦您添加了修改过的文件,它就不再是常规的diff,而是在 git status 结果列表。

    检查什么东西很方便 仍然 是否添加。您可以看到已添加的内容

    git diff --cached
    

    (或者——分阶段,这是同义词)。 如果要取消添加文件,请使用

    git reset <filename>
    

    将索引恢复到head所指的提交状态,而不更改工作树(也就是说, 不要 使用 --hard 这里)。