使用Eclipse启动配置(XML文件)无法让Git正确处理CRLF问题 [英] Can't get Git to correctly handle CRLF problems with Eclipse launch configs (XML files)

查看:163
本文介绍了使用Eclipse启动配置(XML文件)无法让Git正确处理CRLF问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个混合团队,有些人使用Windows,而其他人使用Linux。我们已经配置了IDE(Eclipse)以使用LF作为源代码文件的行结尾,这很好。



但我们也共享启动配置。这些是XML文件,Eclipse会忽略它们的项目设置。为了解决这个问题,我们在 .gitattributes



$ p $ ** / * eol = lf
** / *。launch text

我对这个配置的理解是当Git检查任何扩展名为的文件时。启动,无论树在哪里,它都会将行结尾转换为平台的默认值(不管它们在Git仓库中)。 查看github上的文档


文本



这个设置告诉git总是标准化指定的文件。提交时,它们与LF一起存储,在结帐时它们将被转换为操作系统的本地行结束符。


只有它不起作用。我仍然看到人们提交每行更改的文件; diff -R 根据此答案)显示Git已创建在我的Linux机器上有一个CRLF文件。



git checkout - server.launch 不会改变任何东西。



这里发生了什么?



有没有办法让Git忽略任何行结束符更改在某些文件中?

解决方案

您的问题的根本原因是Eclipse。 Eclipse使用 JGit Java库与Git存储库进行交互。不幸的是,有一个开放的bug(#342372 )添加。 gitattributes 文件支持JGit库。因此,尽管您的 .gitattributes 设置在使用Git客户端时可以使用,但它们会被Eclipse忽略。请参阅此答案以供进一步阅读。



验证上面,下面是一个Bash测试脚本,它将显示JGit不使用 .gitattributes 设置。您可以此处下载自包含的JGit脚本。最终, eol 属性受Git客户端的尊重,并且不受JGit客户端的尊重。

 #!/ bin / bash 

#确保我们有所有必需的程序。
for git jgit od;做
[[! -x`which $ p`]]&& {
echo找不到可执行程序'$ p'!
出口1
}
完成

#让我们看看执行的是什么。
set -x

#创建一个临时Git仓库。
mkdir temprepo
cd temprepo
git init

#更改core.safecrlf配置,以便我们可以使用非本地EOL提交文本文件。
git config core.safecrlf警告

#创建.gitattributes文件。该文件将用于所有递归
#子目录。一个子目录可以有自己的.gitattributes文件,其中
#将覆盖任何父目录中的设置。
echo -en'* eol = lf\\\
* .launch text\\\
'> .gitattributes
git add .gitattributes
git commit -m'添加.gitattributes文件。'

#让我们用不同的EOL创建一些测试文件。
echo -en'foo \rbar\r'> cr.launch
echo -en'foo\\\
bar\\\
'> lf.launch
mkdir a
echo -en'foo \r\\\
bar\r\\\
'> a / crlf.launch
git add cr.launch lf.launch a / crlf.launch
git commit -m'添加{cr,lf,crlf} .launch文件''

#让我们看看Git仓库中实际存储的内容。
git show HEAD:cr.launch | od -A x -t x1z -w16
git show HEAD:lf.launch | od -A x -t x1z -w16
git show HEAD:a / crlf.launch | od -A x -t x1z -w16

#提交不会改变工作目录* .launch文件。
#让我们来检查文件内容。
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a / crlf.launch

#现在让我们更改工作目录中的* .launch文件,将每个Git的设置的EOLs设置为
#。
rm -f cr.launch lf.launch a / crlf.launch
git checkout - cr.launch lf.launch a / crlf.launch

#现在让我们来看看再次文件内容。
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a / crlf.launch

#让我们改变EOL设置并再次检出* .launch文件,看看它们是如何影响
#的。
echo -en'* eol = crlf\\\
* .launch text\\\
'> .gitattributes
git commit -m'更改EOL属性。'.gitattributes
rm -f cr.launch lf.launch a / crlf.launch
git checkout - cr.launch lf.launch a / crlf.launch
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a / crlf.launch

#删除* .launch文件。
rm -f cr.launch lf.launch a / crlf.launch

#现在,让我们使用JGit检出* .launch文件。由于JGit(Eclipse使用的
#Java Git库)中的错误,忽略.gitattributes设置;
#签出* .launch文件不会有CRLF EOL。
jgit reset --hard HEAD
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a / crlf.launch


We have a mixed team with some people using Windows and others using Linux. We have configured the IDE (Eclipse) to use LF as line ending for source files which works well.

But we also share launch configs. These are XML files and Eclipse ignores the project settings for them. Instead, it always uses the platform's line ending when writing the file.

To solve this, we have these lines in .gitattributes:

**/*            eol=lf
**/*.launch     text

My understanding of this configuration is "when Git does a checkout of any file with the extension .launch, no matter where in the tree, it will convert the line endings to the platform's default (no matter what they were in the Git repo)". See the docs on github:

text

This setting tells git to always normalize the files specified. When committed they are stored with LF, on checkout they are converted to the OS's native line endings.

Only it doesn't work. I'm still seeing people committing files where every line changed; diff -R (as per this answer) shows that Git created a file with CRLF on my Linux box.

git checkout -- server.launch doesn't change anything.

What is going on here?

Is there a way to tell Git to simply ignore any line ending changes in some files?

解决方案

The root cause of your problem is Eclipse. Eclipse uses the JGit Java library to interface with Git repositories. Unfortunately, there is an open bug (#342372) to add .gitattributes file support to the JGit library. So, though your .gitattributes settings will work when using the Git client, they are ignored by Eclipse. See this SO answer for further reading.

To validate the above, below is a Bash test script that will show JGit does not use the .gitattributes settings. You can download a self-contained JGit script here. Ultimately, the eol attribute is respected by the Git client and is not respected by the JGit client.

#!/bin/bash

# Make sure we have all the required programs.
for p in git jgit od; do
    [[ ! -x `which $p` ]] && {
        echo "Could not find executable program '$p'!"
        exit 1
    }
done

# Let's see what is being executed.
set -x

# Create a temporary Git repo.
mkdir temprepo
cd temprepo
git init

# Change core.safecrlf config so we can commit text files with non-native EOLs.
git config core.safecrlf warn

# Create the .gitattributes file.  This file will be used in all recursive
# sub-directories.  A sub-directory can have its own .gitattributes file which
# would override the settings in any parent directories.
echo -en '* eol=lf\n*.launch text\n' >.gitattributes
git add .gitattributes
git commit -m 'Add .gitattributes file.'

# Let's create some test files with different EOLs.
echo -en 'foo\rbar\r' >cr.launch
echo -en 'foo\nbar\n' >lf.launch
mkdir a
echo -en 'foo\r\nbar\r\n' >a/crlf.launch
git add cr.launch lf.launch a/crlf.launch
git commit -m 'Add {cr,lf,crlf}.launch files.'

# Let's see what is actually stored in the Git repo.
git show HEAD:cr.launch | od -A x -t x1z -w16
git show HEAD:lf.launch | od -A x -t x1z -w16
git show HEAD:a/crlf.launch | od -A x -t x1z -w16

# The commit would not have changed the working directory *.launch files.
# Let's inspect the file contents.
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a/crlf.launch

# Now let's change the *.launch files in the working directory to have EOLs as
# per Git's settings.
rm -f cr.launch lf.launch a/crlf.launch
git checkout -- cr.launch lf.launch a/crlf.launch

# Now let's inspect the file contents again.
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a/crlf.launch

# Let's change the EOL setting and checkout the *.launch files again to see how
# they are affected.
echo -en '* eol=crlf\n*.launch text\n' >.gitattributes
git commit -m 'Change EOL attribute.' .gitattributes
rm -f cr.launch lf.launch a/crlf.launch
git checkout -- cr.launch lf.launch a/crlf.launch
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a/crlf.launch

# Remove the *.launch files.
rm -f cr.launch lf.launch a/crlf.launch

# Now, let's checkout the *.launch files using JGit.  Due to a bug in JGit (the
# Java Git library Eclipse uses), the .gitattributes settings are ignored;
# checked out *.launch files will not have CRLF EOLs.
jgit reset --hard HEAD
od -A x -t x1z -w16 cr.launch
od -A x -t x1z -w16 lf.launch
od -A x -t x1z -w16 a/crlf.launch

这篇关于使用Eclipse启动配置(XML文件)无法让Git正确处理CRLF问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆