git diff显示完整文件已更改,仅更改了一行,但仅对目录中的几个文件进行了更改 [英] git diff is showing full file has changed for a single line change but only for few files in a directory

查看:865
本文介绍了git diff显示完整文件已更改,仅更改了一行,但仅对目录中的几个文件进行了更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 GIT 中遇到了一个奇怪的问题.最近,我们的代码库已从SVN迁移到GIT.因此,当我在本地上克隆存储库并且在文件中进行单行更改时,git diff显示整个文件已更改(首先删除了所有内容,然后又添加了所有内容).但是奇怪的是,并不是所有文件都发生这种情况.

I have come across a strange problem in GIT. Recently our codebase has moved to GIT from SVN. So, when I have cloned the repository on my local and I am doing single line change in a file, git diff is showing full file has changed (first all the content has deleted and then all the content added again). But strange thing is it's not happening for all the files.

例如我已经更改了(例如在行后添加了空格)我的app.jsindex.htmlgruntfile.js,其中显示了app.js的正确行差异以及index.htmlgruntfile.js

e.g. I have changed (e.g. added a space after a line) my app.js, index.html and gruntfile.js where it's showing correct line diff for app.js and full file change for index.html and gruntfile.js

我引用了许多stackoverflow文章,并将core.autocrlf设置为truefalse,但是没有一个设置起作用.

I have referred many stackoverflow articles and set core.autocrlf to true and false both but none of the setting worked.

另一个奇怪的事情是我也无法重置该文件.假设在上面的示例中,如果我执行git reset --hard,它不会从本地删除/还原有缺陷的文件,此处的app.js已还原,而其他两个未还原.最后,我不得不使用git checkout .还原所有文件.

Another strange thing is I am unable to reset that file also. Suppose in the above example if I do git reset --hard, it doesn't remove/revert the defected files from my local, here app.js has been reverted but other two did not revert. Finally I had to use git checkout . to revert all the files.

更新:这是我的.gitattribute文件内容,位于根目录中. * text=auto

Update: This is my .gitattribute file content in the root directory. * text=auto

这是我在根目录中的.editorconfig文件.

And this is my .editorconfig file in the root directory.

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

推荐答案

这听起来像是CRLF和LF线路末端出现问题.

This sounds like a problem with CRLF vs LF line endings to me.

我相信SVN和GIT都将文本文件存储在带有LF行尾的存储库中,并且当从工作副本中检入和检出存储库中的文件时,它们都在LF和CRLF行尾之间进行转换.

I believe that SVN and GIT both store text files in their repositories with LF line endings, and that both convert between LF and CRLF line endings when checking files in and out of the repository from the working copy.

不幸的是,SVN和GIT具有不同的方式来决定哪些文件是文本文件,因此它们并不总是就是否需要行尾转换而达成共识.

Unfortunately SVN and GIT have different ways of deciding which files are text files, so they don't always agree on whether line ending conversion is required.

GIT很擅长猜测,但是允许使用属性进行控制-运行"git help属性"以获取解释.

GIT is pretty good at guessing but allows control using attributes - run "git help attributes" to get an explanation.

SVN在单个文件上使用svn属性,这些属性要么必须手动设置,要么通过已配置的自动道具规则设置.

SVN uses svn properties on individual files, and these properties either have to be set manually or else via configured auto-props rules.

我猜测文件最初是在Windows上提交给SVN的,您正在Windows上运行GIT的,并且您是使用"git svn"创建的GIT存储库的.

I'm guessing that the files were originally committed to SVN on Windows, that you're running GIT on Windows, and that you created the GIT repository using "git svn".

如果是这样,那么我最好的猜测是您的SVN储存库未设置svn属性,因此SVN将具有CRLF行尾的文件存储在SVN储存库中,而没有进行转换.然后,如果您使用"git svn"将SVN储存库导入到新的GIT储存库中,则GIT储存库还将包含CRLF行尾.这不是GIT储存库中文本文件的预期格式,因此可能会导致问题.特别是,我认为"git diff"将存储库中已有的内容(具有CRLF行结尾)与将提交给存储库的内容(具有LF行结尾)进行比较,发现每一行都是不同的.

If so then my best guess is that your SVN repository didn't have svn properties set, so SVN stored files with CRLF line endings in the SVN repository without conversion. If you then imported the SVN repository into a new GIT repository with "git svn" then the GIT repository will also contain CRLF line endings. This is not the expected format for text files in the GIT repository, so it can cause problems. In particular, I think "git diff" compares what is already in the repository (with CRLF line endings) with what would be committed to the repository (with LF line endings) and finds that every line is different.

一种了解正在发生的情况的方法是将存储库克隆到具有core.autocrlf = false(或未设置)的Linux机器上.在这种情况下,不会有任何CRLF行尾转换引起混淆,您可以看到检出文件中的行尾是什么.我的猜测是,由于CRIT的行尾存储在GIT存储库中,因此它们将具有CRLF的行尾.

One way to understand what's going on would be to clone the repository to a Linux machine with core.autocrlf = false (or not set). In this case there wouldn't be any CRLF line ending conversion to confuse the matter, and you could see what the line endings in the checked out files are. My guess is that they'll have CRLF line endings because of CRLF line endings stored in the GIT repository.

如果我的假设正确,那么我认为您有2个选择:

If my hypothesis is correct then I think you have 2 options:

(1)修复GIT存储库,使其包含LF而不是CRLF行尾. 在Windows上(使用core.autocrlf = true),我认为您可以通过触摸每个文件(不进行任何更改),然后提交GIT报告为已更改的所有文件来执行此操作. 在Linux(带有core.autocrlf = false)上,我认为您可以通过在所有文本文件上运行dos2unix然后提交来实现.

(1) Fix the GIT repo to contain LF rather than CRLF line endings. On Windows (with core.autocrlf=true) I think you could do this by touching every file (without making any changes), then commit all files that GIT reports as changed. On Linux (with core.autocrlf=false) I think you could do it by running dos2unix on all of the text files and then committing them.

(2)将所有文件都视为二进制文件而不是文本文件,以使GIT根本不尝试行尾转换.我认为您可以通过提交包含"* -text"(不带引号)的.gitattributes文件来实现此目的.这样做的缺点是,在Linux上签出时会得到CRLF行尾.

(2) Treat all files as binary rather than text so that GIT doesn't attempt line ending conversion at all. I think you could do this by committing a .gitattributes file containing "* -text" (without the quotes). The disadvantage of this is that you'll get CRLF line endings when checking out on Linux.

这篇关于git diff显示完整文件已更改,仅更改了一行,但仅对目录中的几个文件进行了更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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