之前写过一篇博客“探索TFS Git 库文件换行(CRLF)的处理方式”,主要是针对TFVC代码库的。
下面这篇文章说明如何在TFS的Git库中处理代码换行的问题。
概述
在Azure DevOps Server(之前叫TFS) 中使用Git管理源代码,需要特别注意代码文件的换行处理。我们在许多团队碰到这样现象,开发人员在自己的Windows 中使用Eclipse 或者Visual Studio 编写和调试代码,功能都正常。但是,使用TFS 的自动生成和发布功能,将源代码下载到Linux 或 AIX等非Windows 的服务器上做编译和其他操作的时候,发现所有的功能都乱套的,甚至连基本的编译都无法成功。排查原因后发现,导致系统异常的原因是文件换行的格式。
我们在编写代码的时候,每次敲击一次回车键,代码会从下一行开始。实际上,我们在代码行的最后面插入了一个不可见的字符,这个字符叫做换行符(line ending)。在历史上,不同的操作系统处理换行符的方式不一样,例如Windows 使用crlf,Linux 使用lf,而早期的mac使用cr,后来有改为lf了。更加详细的内容,可以参考我上一篇博客“探索TFS Git 库文件换行(CRLF)的处理方式”。
在TFS 的Git库中,服务器和客户端对于文件换行符也有自己的处理方式。由于不同的开发人员使用不同的工具和操作系统,例如你使用Windows开发调试,而你的同事使用Mac编写代码,而TFS代理服务器则使用Linux 编译打包。如果不能统一处理换行标准,必然会导致许多未知的问题。例如我们在项目实施过程中,经常碰到这样的问题:“上一次的持续集成成功了,我们没有修改代码,怎么这次就出问题了,怎么这次就失败?”分析原因,TFS服务器在两次持续集成流程中使用了不同的代理服务器,而不同代理服务器上Git客户端处理换行的方式不一样。
解决不同开发人员、不同编译环境处理Git中的源代码换行的问题,我们可以使用下面两个统一的方案:统一开发环境中的Git配置,统一代码库的设置。
解决方案
1. 统一开发环境中的Git配置
在开发人员的计算机上配置Git客户端的全局变量(core.autocrlf),可以强制用户使用指定的方式处理行尾标识符,例如:
$ git config --global core.autocrlf true
# 按照Windows的方式处理换行符
$ git config --global core.autocrlf input
# 按照Linux的方式处理换行符
2. 统一代码库的设置
按照上面的方式处理文件,可以在一台开发计算机上使用统一的标准处理的源代码。但是,在实际开发过程中,需要按照不同的Git库做不同的处理。例如,对于存储.net程序的代码库,我们希望使用Windows的方式来处理换行符;对于java和shell脚本,我们希望使用Linux的方式处理换行符。
Git为我们提供了一种机制,可以针对每个库,设置不同的处理方式。在Git中,有一个特殊的文件.gitattributes。这个文件配置了Git客户端处理代码时候的各种设置(https://git-scm.com/docs/gitattributes) 。我们在每个git库中添加这个文件,再根据自己的需要,修改文件中的设置,就可以实现对不同库不同处理方式。.gitattributes中的设置会覆盖用户在上一章节中的配置。从此以后,无论你的开发人员工作在哪个平台上,只要他下载已经配置.gitattributes文件的代码库,就会按照我们指定的方式处理换行符。
.gitattributes必须放置在代码库的根目录下。保存的方式与我们提交、推送的方式完全一样。你可以把它视为一个普通的代码文件。
.gitattributes文件中的内容有点类型一个两行的表格:
- 左边的内容表示Git库中的文件名称或者文件路径
- 右边的内容表示对代码文件换行符的处理方式
下面是一个简单的示例:
# 使用默认的方式,开发人员客户端如何,git就如何处理换行符
* text=auto# 明确指定使用原文件中的换行符
*.c text
*.h text# 指定扩展名为sln的文件名称,使用Windows的换行符
*.sln text eol=crlf# 指定扩展名为png或jpg的为二进制文件,不需要处理做任何修改
*.png binary
*.jpg binary
从上面的配置,你可以看到,在配置.gitattributes文件时,我们可以使用通配符,例如*.c, *.sln, *.png等。还可以使用空格,在一行中同时指定多种文件。下面,来看一下各种处理文件的配置方式:
- text=auto: Git将按照自己的方式处理文件,一般是按照我们在上一节中配置的方式处理换行符。
- text eol=crlf:在代码克隆、签出时,Git总是将换行符转换为crlf,就是我们Windows常用的格式。即使在Linux或者Mac操作系统中,Git也会按照这种方式处理。
- text eol=lf:在代码克隆、签出时,Git总是将换行符转换为lf,就是我们Linux常用的格式。即使在Windows操作系统中,Git也会按照这种方式处理。
- binary:Git会认为这种文件不是纯文本文件,它对这些文件不做任何处理。
3. 后续处理
按照上面的方式配置了你环境或者Git库后,你会发现实际上本地的文件没有任何变化。原来是Windows换行的,照样还是Windows。但是,实际上Git已经迫切希望按照你设定的方式来文件了。
可以参考下面的方式更新你的本地文件,同时还不会丢失目前的工作成果:
1)立即保存目前的所有文件
git add . –u
git commit –m “在刷新文件换行符之前,保存所有更改”
2)删除Git索引,并且强制Git从小扫描工作目录
rm .git/index
3)重写Git的索引文件,并应用最新的换行设置
git reset
4)查看Git状态
git status
5)将所有修改过的文件添加到提交清单中
git add -u
6)添加.gitattributes文件
git add .gitattributes
7)提交和推送文件
git commit –m “统一文件换行符”
git push
微软DevOps MVP 张洪君 http://www.cnblogs.com/danzhang
--End--