繁体   English   中英

在 git 中跳过工作树以获得 glob 模式

[英]Skipping work-tree in git for glob patterns

我的远程仓库有用于代码执行的.log文件。 因此它们需要被 Git 跟踪。 当其他开发人员在此 repo 上工作时,他们会推送与日志文件相关的更改。 当我拉动这些更改时,它会产生冲突。

为了暂时忽略这些跟踪文件,我尝试了以下选项:

git ls-files *.log* -z | xargs -0 git update-index --skip-worktree

但是,这只会跳过当前存在的日志文件的工作树。 如果其他开发人员将新的日志文件添加到跟踪中,我将需要重新运行此命令。 有没有办法配置 git 来跳过所有具有*.log* glob 模式的文件的工作树?

否(但请参阅底部的脚注 2,这是对您不太了解的问题的回答)。 --skip-worktree选项在现有索引条目上设置一个标志位。 新索引条目永远不会设置或假定未更改或跳过工作树位。

在以下情况下将创建新索引条目:

  • 当文件之前不存在时,您使用git add将文件复制到 Git 的索引中; 或者
  • 您可以使用git checkoutgit switch ,或 Git 的其他索引操作命令之一,将文件复制到以前不存在的 Git 索引中。

如果其他开发人员将新的日志文件添加到跟踪中...

重要的是要意识到,除非您共享存储库本身(这通常是一个坏主意),否则其他开发人员不会更改要跟踪的文件,因为对于某些工作树文件,已跟踪与未跟踪的概念基于您的存储库和工作树。

那是:

  • Git 是关于commits 的 用户进行新的提交并将它们添加到他们的 Git 存储库中,然后您将 Git 存储库连接到他们的 Git 存储库(或连接到他们已将提交发送到的某个中央共享站点)并从他们那里获取提交。 (也就是说,他们可能会在他们的存储库中运行git push ,这会将他们的提交发送到中央共享站点。然后运行git fetch origin将这些提交放入您自己的存储库中。如果您使用的是git pull ,请注意git pull首先运行git fetch ,然后运行第二个 Git 命令来处理获取的提交。)

  • 虽然提交包含文件,但提交中的文件是只读、压缩和重复数据删除的格式,只有 Git 本身可以读取。 这些文件一直处于冻结状态。 它们本身没有用处。 (但它们去重的,所以如果数百个提交在某个文件中有相同的数据——这通常是这种情况,因为每个提交都包含每个文件——实际上只有一个文件副本,由所有这些提交共享.)

  • 因此,当您git checkout特定提交时,您的Git 会从给定提交中复制文件。

所以这里的主要思想是,当您处理某个提交时,该提交的文件有两个副本。 一个是冻结的仅限 Git 的副本,位于当前提交中,另一个是您可以读写并通常使用的副本,位于您的工作树工作树中 在这里,Git 就像大多数版本控制系统一样:它们都必须做这样的事情,因为有一个确实无法更改的提交副本,以及一个可以更改的可用副本。

但是在这里,Git 与其他版本控制系统不同,它在冻结的提交副本和可用的工作树副本之间保留了第三个副本。 第三个副本实际上并不是真正的副本,因为它是 Git 的冻结格式,并且已经进行了重复数据删除。 它与提交副本的不同之处在于它不在提交中:它在 Git 的index 中 这意味着您可以通过替换某个其他文件的新的重复数据删除副本来批量替换它。

这就是git add所做的:它创建一个全新的索引条目,以保存文件名和新的但已经去重(Git blob 对象)的文件内容; 或者它替换现有条目的内容(内部 blob 对象哈希 ID),同时保留现有索引条目中的文件名和标志。 1这是您的--skip-worktree标志出现的地方。

索引,Git 也称为staging area ,只包含进入下一次提交的文件的条目。 这些是 Git 知道的文件。 它们现在已经在 Git 的索引中 索引包含文件的名称和模式、一个去重的内部 Git blob 对象哈希 ID,以及一堆 Git 认为有用的其他缓存信息。 这包括跳过工作树位。

但由于该指数代表了下一代承诺,你会做,它包含那些将在未来提交的文件。 如果一个文件不存在,它就不能在下一次提交中——所以它不在索引中,因此它没有跳过工作树位。

类似地,因为索引代表您将进行的下一次提交,所以当您使用git checkout选择要处理/使用的提交时,Git将从该提交中填充其索引,因此下一次提交是相似的。 假设有人在新提交中创建了一个以前从未存在过的新日志文件。 一旦您让 Git 检查此提交,Git 将需要将日志文件添加到其索引中。 这将是一个新条目,并且不会设置跳过工作树位。

这也将我们带到了未跟踪文件的定义,因此相比之下,是跟踪文件。 未追踪文件是在你的工作树,现在,是不是在Git的指数,现在的任何文件。 因此,一个跟踪的文件就是现在在 Git 索引中的文件。 这就是它的全部,但是:

  • 您的工作树在您的控制之下:您可以随时创建和删除文件。
  • Git 的索引在 Git 的控制之下。 签出一个提交来填充它。 但是您也有一些控制权: git add副本到其中, git rm从 Git 的索引和您的工作树中删除。

由于您只能在索引条目上设置假设未更改和跳过工作树标志,因此您只能在(当前)跟踪的文件上设置它们。 当您从一个提交切换到另一个提交时,这组跟踪文件至少可能会发生变化。 如果要在特定索引条目上设置特定位,则必须在从一个提交切换到另一个提交时执行此操作。 2


1因为git add意味着使索引副本与工作树副本匹配,所以git add可以从索引中删除工作树中不再存在的任何文件。 但是,设置跳过工作树位后, git add不会使索引副本与工作树副本匹配:它不会将更新的文件复制回 Git 的索引,也不会从 Git 的索引中删除,工作树中缺少的任何文件。 第二部分与脚注 2 直接相关。

2这并不完全正确:Git 支持称为sparse checkouts 的东西,Git 会在某些新索引条目上故意设置跳过工作树位。 这实际上是跳过工作树位的初衷。 但是,它的工作方式是为 Git 列出应该出现在工作树中的文件。 如果文件被标记为“由于稀疏检出而不检出”,Git 将确保不会将已提交(现在已编入索引)的文件复制到您的工作树中。 也就是说, git checkout将看到不应git checkout此文件,而是设置跳过工作树位。

这里的问题是当然这些文件不会出现在您的工作树中。 也就是说,这些*.log*文件根本不会被检出。 它们将在 Git 的索引中,因此将在您进行的新提交中,但您将无法查看这些文件。 这对于您的特定目的可能没问题。 在这种情况下,停止手动设置位,并查看稀疏结帐。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM