git diff is showing full file has changed for a single line change but only for few files in a directory

11,857

Solution 1

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

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.

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 is pretty good at guessing but allows control using attributes - run "git help attributes" to get an explanation.

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

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".

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.

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.

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

(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) 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.

Solution 2

execute below command

cd repo<Project>
git config --global core.autocrlf true

Solution 3

This is expected behavior of GitLab and there is nothing wrong in this case. See the issue( https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52936). We may skip those white space changes from compression using GitLab UI. Steps to hide/ignore white space changes.

  1. Go to your merge request.
  2. Navigate to change between section.
  3. Click on the setting button, from right side of "change between section"
  4. Unchecked the option "Show whitespace changes"

After doing this you the compare section will show only real changes. Below is the screenshot which you refer.

enter image description here

Share:
11,857
Debajit Majumder
Author by

Debajit Majumder

Updated on June 18, 2022

Comments

  • Debajit Majumder
    Debajit Majumder almost 2 years

    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.

    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

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

    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.

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

    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