Git:从源代码控制的文件中删除回车符

22

我有一个Git存储库,其中一些文件采用DOS格式(\r\n行结尾)。 我想只需通过运行文件进行dos2unix(这将把所有文件更改为UNIX格式,带有\n行结尾),但这会对历史记录产生多大影响,是否推荐这样做?

我认为标准是始终使用UNIX行结尾的源代码控制文件,并在本地选择特定于操作系统的行结尾。


1
对于对此感兴趣的人的相关问题,请参考:http://stackoverflow.com/questions/446244/are-crlf-lines-ok-in-a-rails-project-deployed-on-linux - Blixt
4个回答

37
这个crlf问题让我们在从svn转换到git(在一个中央(bare) scm环境中)时非常困扰。最终让我们受挫的是我们将全局.gitconfig文件复制到每个用户根目录下(包括Windows和Linux),初始版本来自一个Windows系统,其中core.autocrlf=true,core.safecrlf=false,在Linux用户中造成了混乱(例如bash脚本无法工作以及所有可怕的^M)。所以,最初我们编写了一个checkout和clone脚本,这些命令之后会执行dos2unix。然后我发现了核心的autocrlf和safecrlf配置项,并根据操作系统设置它们:
Windows: core.autocrlf=true and core.safecrlf=false Linux: core.autocrlf=input and core.safecrlf=false 这些是用以下命令设置的: ---在Windows上---
git config --global core.autocrlf true
git config --global core.safecrlf false

---在Linux上---

git config --global core.autocrlf input
git config --global core.safecrlf false

那么对于我们的Linux开发人员,我们设置了一个小的bash脚本/usr/local/bin/gitfixcrlf:

#!/bin/sh
# remove local tree
git ls-files -z | xargs -0 rm
# checkout with proper crlf
git checkout .
他们只需要在本地沙盒克隆上运行一次。以后任何克隆都是正确的。现在任何未来的推送和拉取都将被正确处理。因此,这解决了我们使用换行符时遇到的多个操作系统问题。还要注意Mac与Linux具有相同的配置。

14

你需要采用的方法取决于你的代码库是否公开。

如果你不介意或者并不关心更改所有的SHAs(Git版本号),因为你是唯一使用它的人,但是想要一劳永逸地解决这个问题,你可以运行git filter-branch命令,并对每个提交中的所有文件应用dos2unix命令。(如果你共享代码库,则其他人需要彻底更新它,所以这可能有潜在风险。)

因此,更好的选择也更容易的方法是仅在当前提交中进行更改。这意味着您过去的提交仍然具有\r\n换行符,但除非您从过去大量合并提交,否则这不应该是问题。当然,差异工具可能会稍微多报告一些警告,但通常你只和相邻的提交比较,随着提交的积累,这个问题就解决了。

而UNIX换行符是标准的,你是正确的。最好的方法是设置你的编辑器,即使在Windows上也只写这些换行符。否则,您还可以使用autocrlf设置。


关于历史重写部分的补充:

上一次我做同样的事情时,我使用了以下命令将所有文件更改为UNIX换行符。

#!/bin/bash
all2dos() { find * -exec dos2unix {} \; }
export -f all2dos
git filter-branch -f --tree-filter 'all2dos' --tag-name-filter cat --prune-empty -- --all

谢谢。目前只有我一个人在这个代码库上工作,因为它还比较“年轻”,所以重写历史应该不是问题。但是git filter-branch和GitHub会有什么样的兼容性(我已经将代码库放在GitHub上了)? - Blixt
我认为,您需要删除GitHub上的所有分支和标签,以确保它们可以重新创建。(这可能可以不这样做,但最好重新开始。)或者,您可以删除整个存储库,然后再次推送它。这对于GitHub来说应该是可以接受的,除非有些人已经从中克隆了。然后,他们将需要根据他们在Git上的熟练程度进行相同的操作。 - Debilski
好的。我刚刚删除了仓库,并重新推送了具有重做历史的版本。无论如何,我需要修复一些旧提交消息也是多行的问题。 - Blixt
1
你发布的代码对我来说效果不佳,所以我写了以下代码:git filter-branch --tree-filter 'grep -Irl --exclude-dir=.git "" . | xargs sudo dos2unix -p' HEAD - Blixt
3
Git能否识别文件是文本文件还是二进制文件?因为dos2unix无法处理二进制文件,所以在包含文本文件和二进制文件的GIT存储库中运行时,如何处理这个问题? - Senthil A Kumar

4
对于持续的解决方案,请查看core.autocrlf(和core.safecrlf)配置参数
对整个代码库执行此操作只会创建一个提交记录,很难合并(因为这些文件中的每一行都将被修改),但是一旦完成,就不应该有太大问题。(是的,您可以使用git filter-branch来使修改在整个历史记录中生效,但这有点可怕。)

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接