如何更改.gitattributes生效

eve*_*tic 9 git attributes line-endings

我正在开发一个我们最近开始使用git的项目.设置从一开始就不完美,所以我在人们开始克隆/工作后设置了.gitattributes,我仍在对这个文件进行一些更改.

考虑以下设置......

Alice和Bob都克隆了"repo.git",并且存储库包含文件/myproj/src/file.ending,其中包含\n行结尾,即文件不包含\r字符.

它们都具有.gitattributes以下设置:

/myproj/src/file.ending -text
Run Code Online (Sandbox Code Playgroud)

这告诉git不file.ending应该被视为文本文件,因此不应该进行行结束转换.

因此,Alice和Bob的工作树中的文件也有\n行结尾.

现在,Alice对.gitattributes进行了以下更改:

/myproj/src/file.ending text
Run Code Online (Sandbox Code Playgroud)

爱丽丝希望这一改变能够为她和鲍勃生效.

我现在知道的唯一方法是非常侵入性的:

git rm --cached -r .
git reset --hard
Run Code Online (Sandbox Code Playgroud)

我想避免两件事:

  • Alice在实际测试之前必须提交她的`.gitattributes`文件(上面的重置将覆盖她的更改).
  • Bob必须擦除他的索引和工作树才能获得更新.鲍勃不高兴.

这样做的首选方式是什么?

Rat*_*ata 11

您不必硬重置(如果我正确理解您在做什么)。

我的情况类似。我.gitattributes在一个正在运行的项目中添加了一个。我需要我拥有的文件和在线 repo 中的文件由 gitattr 控制。

# This will force git to recheck and "reapply" gitattributes changes.
git rm --cached -r .
git add -A
Run Code Online (Sandbox Code Playgroud)

您的提交将重新添加.ending您提到的所有文件,并且您不会丢失任何您可能拥有的更改。当然,鲍勃必须拉动才能得到它。

  • 这有一个很大的问题。它将添加未版本化且不应该存在的文件。 (6认同)
  • 事实上,这个解决方案必须有一个巨大的警告。对于任何中型到大型存储库,这绝对不是一件好事 (2认同)

Mar*_*ger 6

通过“希望此更改生效”,您的意思是 Alice 希望她和 Bob 的工作副本都切换到 Windows 样式的行尾?那么第一个问题是,为什么爱丽丝要对鲍勃的工作树中的内容负责?

如果新属性更好地描述了文件,那就这样吧;该.gitattributes文件可以像任何其他文件一样进行编辑、测试和提交。

您建议的使新属性生效的过程没有多大意义,原因有二:

首先,为什么要擦除索引?text 属性影响索引和工作副本之间的关系。在您的示例中,它似乎是您需要更改的工作副本,而不是索引。

其次,为什么要从索引中擦除所有内容?只需要处理属性发生变化的路径。

所以在你的例子中,如果爱丽丝想在本地反映新属性,最需要的是

rm myproj/src/file.ending
git checkout -- myproj/src/file.ending
Run Code Online (Sandbox Code Playgroud)

由于此过程不会覆盖 .gitattributes 文件,因此无需提前提交。

我不清楚到底是什么让鲍勃对你的原始程序不满意,所以我不知道这是否让他更快乐。也许他只是希望拉动时自动更新;虽然期待这一点并非不合理,但我不确定它是否在 git 工作的卡片中。

问题是如何检测变化。在几乎所有情况下,如果 git 在合并或快进结束时更新工作树(例如完成拉取),它只需要比较旧提交和新提交的索引对象的哈希值,以判断是否存在要应用的更改。

例外情况是,如果属性(或过滤器定义)发生变化 - 如上所述,索引不会发生变化。但是这些条件相对较少,而且对它们的检查比几乎每次都正确的哈希检查昂贵得多,因此与其用几乎毫无意义的成本进行每次比较,git 允许当您知道自己做了某些事情时,您必须采取额外的步骤。

因此,如果这将发生一次,请让团队进行沟通。“此路径的属性正在更改;您可能需要刷新受影响文件的工作副本。”

如果它会反复发生,我最好的建议是弄清楚为什么会不断发生并解决它。您可以尝试设置某种脚本自动化,甚至可以使用钩子来检测和解决属性更改;但它有很多复杂性,并且可能会造成比修复更多的麻烦。

  • 关于 Alice 和 Bob 之间的同步,我不明白您想知道为什么 Bob 想要这些更改。正如您所说, .gitattributes 更改更自然地描述了文件,Bob 希望利用此描述。我正在擦除整个索引,因为使用一个特定文件只是一个例子。似乎 rm 单独(而不是 git rm)也很有用。所以你可以用它来代替。不知道。正如对我的原始文本的评论中所述,“触摸”似乎也有效,并且可能被认为不那么具有侵入性。 (2认同)

Iwa*_*amp 5

osseirc://chat.freenode.net/#git给了我这个方法,和它的作品相当不错:

git rm -r :/ && git checkout HEAD -- :/
Run Code Online (Sandbox Code Playgroud)

如果您的树中有未提交的更改,这将抱怨。

不过似乎应该有更好的方法。

  • 这个答案不适用于 Windows Powershell,因为它没有“&&”([ref](/sf/ask/1057119381/)) 。在 Powershell 上,使用 `git rm -r :/; git checkout HEAD -- :/`. (3认同)