Azure DevOps Server (TFS)中代码文件换行问题解决方案(Git)

之前写过一篇博客“探索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--

上一篇:RabbitMQ分布式集群架构和高可用性(HA)


下一篇:jvm问题