我正在尝试在所有提交中将 CRLF(windows 行结尾)替换为 LF(unix 行结尾)。
我发现你可以使用这个配置:
git config --global core.autocrlf input
但根据我的理解,这将在未来的提交中用 LF 替换 CRLF,而不是在我的存储库中已有的提交中。
最佳答案
可以更改您的存储库中的历史记录,以便看起来始终使用 LF;但这不是一个简单的过程,并且需要付出一定的成本(这可能重要也可能不重要,具体取决于您的存储库的使用方式)。您可能想仔细看看为什么您希望所有提交都具有 LF,并看看是否有更简单的方法来获得您想要的结果。
(例如,如果您正在使用一个使用 LF 行结尾的系统,并且只想在每次 checkout 文件时都将文件规范化为该标准,那么您也许可以使用过滤器来实现这一点 - 这基本上是相同的想法就像当存储库包含(至少一些)LF行结尾时 autocrlf 对 Windows 用户所做的那样。这不是纯粹的解决方案,但它避免了历史重写的中断,所以如果它满足您的需求,它可能是更好的实践中的解决方案。)
如果出于某种原因您确实需要更改存储在历史记录中的行结尾,那么您必须重写历史记录。也就是说,您必须将当前具有 CRLF 行结尾的所有提交替换为已替换行结尾的新提交。
这意味着所有提交 ID(哈希)值都会发生变化,因此,如果您将这些值用于任何内容(例如发布文档或其他内容),则它要么需要更新,要么就会过时。这还意味着存储库的任何其他克隆(在构建服务器上或由其他开发人员使用)都需要更新。基本问题(以及重写分支历史记录时解决该问题的方法)可以在“从上游 rebase 恢复”下的 git rebase 文档中找到,但是对于全面的历史记录重写,最好让每个人都参与将所有更改推送到中央存储库,然后丢弃所有克隆,然后重写中央存储库的历史记录,然后让每个人重新克隆。如果这在您的情况下不切实际,那么我强烈建议不要尝试重写,因为如果有人在重写后尝试恢复时做错了事情,则重写可能会被撤消。
话虽如此,如果您决定这样做,该怎么做?
如果历史记录很小且简单,您可以使用rebase
。例如,给定一个小的线性历史记录,您可以说 git rebase -i
,将所有提交的命令更改为 edit
,并查找并修复所有文件中的行结尾对于每个提交。不过,这很快就会变得乏味,如果您有任何“真实”的历史记录,您将需要更自动化的东西。
在最常见的情况下,您可以使用git filter-branch
。最简单的方法是使用树过滤器
;您将编写一个脚本来重写工作树中的所有行结尾(在本例中,我们将调用 filter.sh
,然后给出类似的命令
git filter-branch --tree-filter filter.sh -- --all
如果存储库很大(大量提交和/或非常大的工作树),那么该命令将花费很长时间。您可以通过为 filter-branch
提供一个 ramdisk 来放置其工作树来加快速度,但这仍然是一个资源密集型操作。
使用索引过滤器
会更快(但仍然可能不是“快”)。不过,它更复杂。可能您会预处理每个 BLOB(文件对象)历史记录,生成一个替换了行结尾的版本;然后您的脚本将运行命令来更新索引,通过将每个“旧”BLOB 替换为相应的新 BLOB。
我意识到最后一段涉及了一些并非每个人都知道的术语和概念,这就是重点。如果您了解得足够多,或者值得学习足够多的知识来理解和组装这样的过程,那么这是一个选择,并且它比使用树过滤器更快。
关于git - 在所有提交中将 CRLF 替换为 LF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54422721/