Git自动换行符

本文介绍了不同操作系统下的换行符格式及跨平台协作时的处理方法,详细解析了Windows、Unix/Linux、MacOS等系统中回车(CR)与换行(LF)的区别,并提供了Git配置策略。

Welcome to my personal blog: www.freehacker.cn


不同的操作系统有不同的换行符格式,跨平台协作时需要考虑版本工具(git)对换行符的处理<!--more-->

回车和换行


回车(Carriage Return)和换行(Line Feed)概念:

  • 回车CR:将光标移动到当前行开头;
  • 换行LF:将光标“垂直”移动到下一行,并不改变光标水平位置。

以上的概念只适用于打字机,现代计算机沿用的时候主要使用的是回到行首换行+回到行首的功能。看下面的例子:

1、在Windows下应用程序输出\n到文件,会被自动转换成\r\n

// output:
// first line
// second line
printf("first line\nsecond line");

// test.txt output;
// first line\r\nsecond line
std::fstream fout("test.txt", std::ios::out);
if (fout.is_open())
{
    fout.write("first line\nsecond line", sizeof("first line\nsecond line"));
    fout.close();
}

2、在windows下应用程序输出\r到文件,不会被转换,并且并不会起到“将光标移动到当前行开头”的作用

// output:
// second line
printf("first line\rsecond line");

// test.txt output;
// first line\rsecond line
std::fstream fout("test.txt", std::ios::out);
if (fout.is_open())
{
    fout.write("first line\rsecond line", sizeof("first line\rsecond line"));
    fout.close();
}

3、在Windows下应用程序输出\r\n到文件,\r\n会被自动转换成\r\r\n

// output:
// first line
// second line
printf("first line\r\nsecond line");

// test.txt output;
// first line\r\r\nsecond line
std::fstream fout("test.txt", std::ios::out);
if (fout.is_open())
{
    fout.write("first line\r\nsecond line", sizeof("first line\r\nsecond line"));
    fout.close();
}

不同系统下的换行符


CR、LF、CR/LF为不同操作系统上使用的换行符:

  • Windows/DOS系统:采用CR/LF表示下一行;
  • Unix/Linux系统:采用LF表示下一行;
  • Mac OS系统:采用CR表示下一行;
  • Mac OS X系统:采用LF表示下一行(Mac OS X已经改成和Unix/Linx一样使用LF)。

CR使用符号'\r',十进制ASCII代码是13,十六进制代码为0x0D;LF使用'\n'符号表示,ASCII代码是10,十六制为0x0A。所以Windows平台上换行在文本文件中是使用 0d 0a 两个字节表示,而UNIX和苹果平台上换行则是使用 0a 或 0d 一个字节表示。

Unix/Linux/Mac系统下的文件在Windows里打开的话(使用Windows自带记事本),会出现换行丢失,所有文字会变成一行,整个文本会乱成一团。Windows系统下的文件在Unix/Linux/Mac里打开的话,在每行的结尾可能会多出一个^M符号。

目前大部分的编辑器和IDE都支持这几种换行符(除了notepad),但是跨平台协作项目源码到底保存为哪种风格的换行符呢?输出的文本需要保存为哪种风格的换行符呢?Git提供了一个解决方案——在跨平台协作场景时,会提供一个“换行符自动转换”的功能。

Git CRLF


Git默认在提交时将Windows换行符(CRLF)转换为LF,在拉取时将UNIX换行符(LF)替换成CRLF。我们可以通过设置autocrlf和safecrlf来设置具体的操作。

autocrlf and saftcrlf

1、autocrlf

// 提交时转换为LF,检出时转换为CRLF
git config --global core.autocrlf true   

// 提交时转换为LF,检出时不转换
git config --global core.autocrlf input   

// 提交检出均不转换
git config --global core.autocrlf false

2、safecrlf

// 拒绝提交包含混合换行符的文件
git config --global core.safecrlf true   

// 允许提交包含混合换行符的文件
git config --global core.safecrlf false   

// 提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn

.gitattributes

.gitattributes文件能够设置每个仓库的换行符配置,摘取Link中的设置为例:

###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following 
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln       merge=binary
#*.vcxproj   merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg   binary
#*.png   binary
#*.gif   binary

###############################################################################
# diff behavior for common document formats
# 
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the 
# entries below.
###############################################################################
#*.doc   diff=astextplain
#*.DOC   diff=astextplain
#*.docx  diff=astextplain
#*.DOCX  diff=astextplain
#*.dot   diff=astextplain
#*.DOT   diff=astextplain
#*.pdf   diff=astextplain
#*.PDF   diff=astextplain
#*.rtf   diff=astextplain
#*.RTF   diff=astextplain

1、text=auto:采用git认为最好的方式来处理文件,未在.gitattributes中设置的项默认按照这种方式处理;

2、text eol=crlf/lf:在checkout时,转换Line Ending为crlf/lf;

3、binary: 告诉git该文件为二进制,防止git修改该文件。

注意:.gitattributes文件必须要提交之后才能生效。

由于目前Jenkins推送到打包服务器上的代码默认采用LF结尾,所以建议仓库内创建.gitattributes文件并设置。

项目实施一


设置原则

本地仓库完全一致,适合单一平台编程

团队设置

一个团队需要使用同一的换行符标准(UNIX标准或者Windows标准),然后配置自己的代码编辑器和IDE,达到两项要求:

  • 在新建文件时默认使用团队统一的换行符标准;
  • 在打开文件时保持现有换行符格式不变(不要做自动转换)。

Git设置

1、关闭换行符自动转换功能

// 提交检出均不转换
git config --global core.autocrlf false

2、开启换行符检查功能(按照需求设置)

// 拒绝提交包含混合换行符的文件
git config --global core.safecrlf true   

// 允许提交包含混合换行符的文件
git config --global core.safecrlf false   

// 提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn

留意每次提交

如果提交的时候变更行数过多(超过自己修改),或者增减行数相同,很有可能是整个文件的换行符被修改了,这个时候就要注意检查了。

项目实施二


设置原则

保证仓库永远换行符永远采用UNIX标准(LF),在Windows工作空间设置为Windows标准(CRLF),在Mac/Linux工作空间设置为Unxi标准(LF),适合跨平台编程

团队设置

统一不同平台下的换行符标准,按照上面设置原则的标准,配置自己的代码编辑器和IDE,,达到两项要求:

  • 在新建文件时默认使用团队统一的换行符标准;
  • 在打开文件时保持现有换行符格式不变(不要做自动转换)。

Git设置

1、设置换行符自动转换功能

# Configure Git on OS X or Linux to properly handle line endings
git config --global core.autocrlf input

# Configure Git on Windows to properly handle line endings
git config --global core.autocrlf true

2、设置换行符检查功能

// 提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn

留意每次提交

1、留意每次提交的更改行数。

2、留意提交时的换行符警告。


### 解决 Git 中与换行符相关的问题 Git换行符问题通常源于不同操作系统之间的差异。Windows 使用 CRLF (Carriage Return Line Feed) 表示换行,而 Linux 和 macOS 则使用 LF (Line Feed)[^3]。当开发者在不同的平台上协作时,这些换行符的不同可能导致意外的行为。 #### 配置全局设置以控制换行符行为 可以通过配置 `core.autocrlf` 来管理换行符自动转换。以下是常见的三种选项及其作用: 1. **`true`**: 在 Windows 上推荐使用的设置。它会将仓库中的 LF 转换为 CRLF,在检出文件时应用到本地编辑器;而在提交时则将 CRLF 转换回 LF 存储于版本库中[^1]。 ```bash git config --global core.autocrlf true ``` 2. **`input`**: 推荐用于 Linux 或 macOS 用户。此模式不会更改已有的 CRLF 文件,但在提交新文件时会将其标准化为 LF。 ```bash git config --global core.autocrlf input ``` 3. **`false`**: 完全禁用任何自动换行符转换操作。如果项目严格要求保持原始换行符,则可以考虑该选项[^2]。 ```bash git config --global core.autocrlf false ``` #### 处理安全换行符警告 通过设置 `core.safecrlf=false` 可以允许提交包含混合换行符的文件。这适用于某些特殊场景下无法完全统一换行符的情况。 ```bash git config --global core.safecrlf false ``` 然而需要注意的是,这种方法仅作为临时解决方案,并不适合长期依赖。 #### 使用 `.gitattributes` 统一团队规则 为了避免因个人配置引起的混乱,建议在项目的根目录创建一个名为 `.gitattributes` 的文件来定义特定类型的文件应该如何处理其换行符[^4]。例如: ```plaintext *.txt text eol=lf *.c text eol=crlf * text=auto ``` 上述例子表示: - 所有 `.txt` 文件强制采用 LF 结束; - 所有 `.c` 文件强制采用 CRLF 结束; - 对其他未指定扩展名的文件启用自动检测功能。 #### 应对中文字符后的换行符异常情况 对于涉及复杂编码环境(如存在大量 UTF-8 编码下的中文字符)可能引发的换行符转换失败现象,可尝试手动调整受影响部分并重新规范化整个文档结构[^5]。具体做法如下: 1. 清除当前索引缓存状态: ```bash rm .git/index ``` 2. 将所有改动标记为新增项后再执行一次完整的提交流程: ```bash git add . git commit -m "Normalize line endings" ``` 这样能够有效减少由于历史遗留原因造成的持续冲突风险。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值