我有一个 Git 存储库,其中包含一些 DOS 格式的文件(\r\n
行尾)。我只想运行这些文件dos2unix
(这会将所有文件更改为 UNIX 格式,并带有\n
行尾),但这会对历史产生多大的影响,是否推荐?
我假设标准是始终对源代码控制文件使用 UNIX 行结尾,并可选择在本地切换到特定于操作系统的行结尾?
我有一个 Git 存储库,其中包含一些 DOS 格式的文件(\r\n
行尾)。我只想运行这些文件dos2unix
(这会将所有文件更改为 UNIX 格式,并带有\n
行尾),但这会对历史产生多大的影响,是否推荐?
我假设标准是始终对源代码控制文件使用 UNIX 行结尾,并可选择在本地切换到特定于操作系统的行结尾?
当我们从 svn 转换为 git(在一个中央(裸)类似的)scm 环境中时,这个 crlf 事情让我们发疯了。最终得到我们的是我们将全局 .gitconfig 文件复制到每个人的用户根目录(是的 Windows 和 linux ),最初的文件来自 Windows 系统,并且 core.autocrlf=true 和 core.safecrlf=false 造成了严重破坏在 linux 用户上(比如 bash 脚本不起作用以及所有那些糟糕的 ^M)。所以我们最初做了一个签出和克隆脚本,在这些命令之后执行了一个 dos2unix。然后我跑了 core.autocrlf 和 core.safecrlf 配置项,并根据操作系统设置它们:
Windows:core.autocrlf=true 和 core.safecrlf=false Linux:core.autocrlf=input 和 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 的配置相同。
您必须使用的方法取决于您的存储库的公开程度。
如果您不介意或关心更改所有 SHA,因为您或多或少是唯一使用它的人,但希望始终解决此问题,您可以运行 agit 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
对于持续的解决方案,请查看 core.autocrlf (and core.safecrlf)配置参数。
对您的整个存储库执行一次此操作只会创建一个几乎不可能合并的提交(因为这些文件中的每一行都会被修改),但是一旦您通过它,它应该没什么大不了的。(是的,你可以用它git filter-branch
来一直修改历史,但这有点吓人。)
如果您的版本控制文件列表包含二进制文件,或者您无法轻松更改历史记录......这里有一个方便的花花公子单线: