Skip to content

解决Windows下Git的问题 #8

@guilixie

Description

@guilixie

背景

刚入职一家新公司,拿到的电脑是Windows系统。这个操作系统大学期间也用的不少了,我熟啊。于是一大波操作之后,开发环境配置总算完毕了。本想着可以开开心心写代码了,没想到一大波坑正在等着我~~~

发现问题

总算熟悉完项目代码,完成了第一个任务,修改了几行代码。墙裂推荐VS Code的插件GitLens,这样一来可以看到每行代码上一次是谁修改,什么时间修改。正因为这个插件,我发现了一个大坑。但遗憾的是在发现问题的时候,我已然提交了代码。

我惊奇地发现,明明只修改了几行代码,为啥选中每行,都显示最后修改的是我?翻看了git log,发现确实这个文件更改是删除所有代码,然后在后面又添加了所有代码,即使肉眼上没有任何更改。

那么问题就来了。以后万一这个文件的代码有bug,而且是历史遗留问题,那岂不是要背锅了。于是,我拍案而起,这也太坑了吧。

分析问题

查阅了资料,了解到了Windows系统下,git会有自动转换换行符的问题。由于项目协作,每个人可能使用不同的操作系统。在换行符上,Win­dows 系统使用的是 CRLF,而 Unix 系统 (包括 LinuxMacOS 近些年的版本) 使用的是 LF。那么就好解释了,我打开文件编辑几行后,可能提交时,整个文件的换行符自动转换了。

CRLF、LF 换行符

CRLFLF 是用来表示文本换行的方式。CR (Car­riage Re­turn) 代表回车,对应字符 \rLF (Line Feed) 代表换行,对应字符 \n。由于历史原因,不同的操作系统文本使用的换行符各不相同。主流的操作系统一般使用 CRLF 或者 LF 作为其文本的换行符。比如Win­dows 系统使用的是 CRLF,而 Unix 系统 (包括 LinuxMacOS 近些年的版本) 使用的是 LF

解决方案

一、修改Git配置

core.autocrlf

Git提供了可以在提交时自动把回车和换行转换成换行,而在检出代码时把换行转换成回车和换行的配置项。

git config --global core.autocrlf [true | false | input]
  • true 提交时转换为LF,检出时转换为CRLF
  • input 提交时转换为LF,检出时不转换
  • false 提交与检出的代码都保持文件原有的换行符不变(不转换)

core.safecrlf

由于没有一种绝对有效的算法来判断一个文件是否为文本,所以Git提供了一项禁止/警告不可逆转换的配置,来防止错误的标准化和转换。它主要影响到多种换行符混合的文件,我们可以手动将其转换成同一种换行符。

git config --global core.safecrlf [true | false | warn]
  • true禁止提交混合换行符的文本文件(git add的时候会被拦截,提示异常)
  • warn提交混合换行符的文本文件的时候发出警告,但不会阻止git add操作
  • false不禁止提交混合换行符的文本文件(默认配置)

core.filemode

Git提供了是否遵从工作树中的文件的可执行位的配置选项,也就是是否区分文件的执行权限。core.filemode选项默认true,即区分文件的执行权限,校验GitIndex中和工作目录中的文件权限。

git config --global core.filemode [true | false]
  • true区分文件的执行权限
  • false不区分文件的执行权限

二、配置IDE的开发环境

建议将IDE的换行格式指定成LF,然后大家都是这种标准提交就可以。

问题仍然存在?

按照上述配置git后,发现还是有这种问题?于是问题矛头就指向VS Code了,因为我安装了许多插件,会不会是插件的问题。

按照之前在其他系统下开发,使用VS Code的插件的经验,GitLens不会有这种显示出错的问题。然后仔细查看打开代码文件的换行符格式,发现都为CRLF(这没什么问题,同事们也使用的是Windows)。就在我按Ctrl+S的时候我发现换行符转换成LF了,于是整个文件都变成我修改的了。

可我明明将VS Code的各种格式化插件的默认换行符格式改成auto,就是不做自动转换。翻阅了资料,问题出在了插件EditorConfig for VS Code

这个插件会使用项目根目录中的.editorconfig文件中的配置,对项目的文件进行格式化。仔细翻看了下配置文件,果然有个配置end_of_line = lf,这个就是直接导致了我之前修改几行,保存后整个文件都修改的罪魁祸首。

终于圆满解决

但是直接把lf改成crlf感觉也不合理,建议都是使用lf,有利于跨操作系统协作。但由于本项目协作者都是在Windows下开发的,所以思来想去,干脆直接先禁用了EditorConfig for VS Code插件。

于是乎,困扰了我半天,让我加班的问题终于被我找到原因和圆满解决了~~

参考资料

  1. 在 Git 中正确设置 CRLF、LF 换行符转换
  2. 自定义-Git-配置-Git
  3. windows下git显示文件被修改,实际没有改动的问题解决办法
  4. VS CODE设置保存时自动将CRLF 转换成 LF
  5. Git对库文件权限的管理与filemode配置详解

Metadata

Metadata

Assignees

No one assigned

    Labels

    GitgitbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions