在所有提交中用LF替换CRLF

时间:2019-01-29 13:58:06

标签: git

我试图在所有提交中用LF(unix行尾)替换CRLF(Windows行尾)。

我发现您可以使用此配置:

dc.Payments.ToList()

但是据我了解,在以后的提交中,这将用LF代替CRLF,而不是在我的仓库中已提交的提交中。

2 个答案:

答案 0 :(得分:2)

可以更改您回购中的历史记录,以便看起来总是使用LF。但这不是一个简单的过程,而且这样做会产生成本(取决于您使用回购协议的方式,这可能会或可能不会重要)。您可能想仔细研究为什么所有提交都具有LF的为什么,并查看是否有更简单的方法来获得所需的结果。

(例如,如果您使用的是使用LF行尾的系统,并且只想在每次签出文件时都将文件标准化为该标准,则可以使用过滤器来完成此操作-基本上是相同的这个想法就像当仓库包含(至少一些)LF行尾时autocrlf对Windows用户的作用一样,这不是纯粹的解决方案,但它避免了历史记录重写的中断,因此,如果满足您的需求,可能会更好解决方案。)

如果出于任何原因您确实确实需要更改行尾,因为它们存储在历史记录中,那么您就必须重写历史记录。也就是说,您必须将所有当前具有CRLF行尾的提交替换为替换了行尾的 new 提交。

这意味着所有提交ID(哈希)值都将更改,因此,如果将其用于任何内容(如发行文档等),则可能需要更新或过时。这也意味着该仓库的其他任何克隆(在构建服务器上,或在其他开发人员使用中)都需要进行更新。基本问题(以及重写分支历史记录时的解决方法)可以在git rebase文档中的“从上游基础恢复中”找到,但是对于全面的历史记录重写,最好让所有人将所有更改都推送到一个中央存储库,然后丢弃所有克隆,然后重写中央存储库的历史记录,然后让每个人重新克隆。如果在您的情况下不可行,那么我强烈建议您不要尝试重写,因为如果有人在重写后尝试恢复时做错事,则重写可能会被撤消。

话虽如此-如果您决定这样做,怎么办?

如果历史记录既短又简单,则可以使用rebase。例如,给定一个小的线性历史记录,您可以说git rebase -i,将所有提交的命令更改为edit,并为每个提交查找并修复所有文件中的行尾。但是,这可能很快就会变得很乏味,而且,如果您有“真实”数量的历史记录,则需要更自动化的东西。

在最一般的情况下,您可以使用git filter-branch。最简单的方法是使用tree-filter;您将编写一个脚本来重写工作树中的所有行尾(在本例中,我们将调用filter.sh,然后输入类似

的命令
git filter-branch --tree-filter filter.sh -- --all

如果存储库很大(大量提交和/或非常大的工作树),那么该命令将花费很长时间。您可以通过给filter-branch一个可放入其工作树的ramdisk来加快速度,但这仍然是资源密集型操作。

使用index-filter会更快(但仍然可能不是“快速”),但是,它涉及的更多。可能是对历史记录中的每个BLOB(文件对象)进行了预处理,从而生成了一个版本替换行尾;然后您的脚本将运行命令,以通过将每个“旧” BLOB替换为相应的新旧索引来更新索引。

我意识到最后一段涉及到了并非每个人都可能知道的一些术语和概念,这就是重点。如果您了解足够多的知识,或者值得学习足够的知识,以了解和组装这样的过程,那么这是一个选择,它将比使用树过滤器更快。

答案 1 :(得分:0)

作为重写所有存储库历史记录的替代方法,您可以使用git对行尾进行 normalize 标准化。

https://www.git-scm.com/docs/gitattributes中,您可以找到有关如何使用--renormalize的{​​{1}}选项的示例。在此示例中,它与git add文件结合使用,但是在更改gitattributes的全局设置时,它也应该起作用。

https://www.git-scm.com/docs/git-add#git-add---renormalize上的描述听起来很像您想要的目标:

  

将“干净”过程重新应用于所有跟踪的文件,以将其再次强制添加到索引中。在更改core.autocrlf配置或text属性后,此功能很有用,以便更正添加有错误CRLF / LF行尾的文件。此选项表示-u。