Git diff too much wrong changes - linux

Im using a windows system to push my changes to a git linux server, where users commit with macOS, could this be the problem of invalid diff changes? changes which are not changes are displayed as deleted and later on re-added as new somehow. im using sublime and also tryed netbeans with the same behaviour...

Windows and *nix based operating system use different line ending character in files. In your case you are adding the Windows Carriage return character in your file and on MacOSX they are removed.
On your Sublime you can change the line ending character on save to match the MacOSX's line ending . See is there a way to convert files line ending on saving. This way you will not see these changes.
You could also instruct git to automatically do the conversion with the core.autocrlf config. See GitHub dealing with line endings

GitHub suggests that you should make sure to only use \n as a newline character in git-handled repos. There's an option to auto-convert:
$ git config --global core.autocrlf true
Of course, this is said to convert crlf to lf, while you want to convert cr to lf. I hope this still works …
And then convert your files:
# Remove everything from the index
$ git rm --cached -r .
# Re-add all the deleted files to the index
# You should get lots of messages like: "warning: CRLF will be replaced by LF in <file>."
$ git diff --cached --name-only -z | xargs -0 git add
# Commit
$ git commit -m "Fix CRLF"
As Per Git Config Manual
core.autocrlf
Setting this variable to "true" is almost the same as setting the text
attribute to "auto" on all files except that text files are not
guaranteed to be normalized: files that contain CRLF in the repository
will not be touched. Use this setting if you want to have CRLF line
endings in your working directory even though the repository does not
have normalized line endings. This variable can be set to input, in
which case no output conversion is performed.

The remote repo has mixed cr/lf lineendings, thought it was unix, now i just set the original lineending if it happens again.

Related

git clone comes with edited files

When I clone a project, I did git status right away and some files appear edited.
I check with git diff . and all edited files have the same message: "warning: CRLF will be replaced by LF".
I didn't even open any files.
git checkout . didn't work.
How is this possible?
On Linux new line mark it is \n, and on Windows it is \r\n, so it looks like when you clone a repository, the operating system changes \r\n to \n and you see the difference

Possible to use git on cross-OS network share?

We have a few work flows where we want to use git repositories mounted on NFS network shares. This generally works well, with the exception of line endings. Obviously, line endings on Linux and Windows differ, so a git status on the CentOS host may show no changes, and a git status in the same directory on Windows shows all files as modified.
Can any of the various git mechanisms to deal with line endings be configured to support this scenario ? We only want Unix-style line endings in our repos, of course, and we don't really care about the Windows SEEING the Unix line endings, but on occasion, a Windows tool will add or accidentally convert files, which we would then not want checked in with those endings.
There are a couple possible solutions here. The best solution depends on whether you care about the endings in the working tree.
If you always want line endings in the repository to be LF, and you don't care about the working tree, you can set the following in the .gitattributes file in your repository (creating it if it doesn't exist):
* text=auto
That will make Git guess whether a given file is binary or text, and if it's text, it will perform conversion to the proper line endings when it's checked out. On Unix, the proper line endings will be LF, and on Windows, usually it will be CRLF (although you can use core.eol to override that).
If you always want line endings in both the objects and the working tree to be LF, then you need to do a little more work. You need to set each individual text file type appropriately with eol=lf:
*.c text eol=lf
*.h text eol=lf
The reason this is necessary is because eol=lf overrides text detection, which means it's not safe to apply to binary files, such as PDFs or JPEG files. If you applied it to all files in your repository, you'd corrupt any binary files that happened to contain a CRLF.
Regardless of which you do, you should do a git add --renormalize . and then a git commit. That will ensure that all of your files in the repository contain LF endings and they'll be checked out with the appropriate endings whenever Git checks them out. That doesn't prevent Windows tools from dirtying the repository with CRLF line endings, but if they do that by accident, only LF endings will be checked in.

Git/Veracrypt EOL hell - cannot discard modified files

Does veracrypt do any sort of file caching in memory that might be preventing changes to my git config files to be recognized?
Long version: I have a repo on a veracrypt partition shared with Windows. While trying to enforce EOL's in my repo, I am seeing files more or less arbitrarily setting EOL's. When making a trivial change to my .gitattributes file, I'll merge this change onto a branch, and suddenly my new branch is filled with files with EOL-only changes.
I'm working on linux using mostly SmartGit or the cmd-line (git v 1.8.3.1). I've tried removed autocrlf and safecrlf or setting to false in both my global and repo config files in case they were confusing things. I've tried deleting my .gitattributes file, or setting
* binary
To prevent any conversion at all.
I have reset dozens of times, and deleted my local repo and re-cloned. But I cannot get rid of these modified files
git rm --cached -r .
git reset --hard
Below is my .gitattributes
# Auto detect text files and perform LF normalization
* text=auto
# Specify LF file endings for coding files
*.txt text eol=lf
*.c text eol=lf
*.cpp text eol=lf
*.h text eol=lf
*.py text eol=lf
*.kl text eol=lf
*.json text eol=lf
# Specify windows-only CRLF endings
*.bat text eol=crlf
*.vcproj text eol=crlf
*.sln text eol=crlf
# Specify binary files - do not modify these files, dammit!
*.so binary
*.dll binary
*.lib binary
*.pdb binary
*.exp binary
*.exe binary
My major problem is that some (not all) .so symlinks are showing up modified in one particular branch - looking for all the world like they've been converted. This consistently occurs in my latest branch, but not earlier branch. In the current spate of madness, my last merge added the *.cpp tag, which promptly converted some (not all) of my *.py files to windows line endings.
Has anyone experienced this kind of unreliability? Is the .gitattributes file supported in this version of git? Is veracrypt or the NTFS partition somehow confusing things on me?
I've been working on what should be a trivial task for a week now, and simply cannot fathom how git is deciding on its EOL strategy.
I still don't know precisely what is going wrong, but I recreated the repo, and as long as I never touch (use it read-only) it in windows it seems ok.

How to get Git to convert CRLF files to LF, on Linux?

I'm trying to do something very simple: check out a repo that has CRLF endings (and no .gitattributes) file, and end up with native (LF) line endings. I don't even want to commit back.
I've read Github's suggestion, and Tim Clem's article, but mostly they seem aimed at Windows developers.
I've tried this:
$ git config --global core.autocrlf=input
$ git clone https://github.com/DennisSchiefer/Project-OSRM-Web.git
But no - the file I care about, OSRM.Config.js, still has CRLF endings.
Trying core.autocrlf=true didn't help.
Even adding and committing a .gitattributes file (then git rm --cached -r . && git reset --hard) doesn't help.
I can't find any combination that will actually leave LF line endings on this file.
core.autocrlf will force git to process all text files.
If OSRM.Config.js is not processed, that means Git deems it binary.
See:
"How to determine if Git handles a file as binary or as text?"
"Why does Git treat this text file as a binary file?"
Even with a .gitattributes with *.js text, that would still keep crlf.
But with *.js eol=lf, that would actually force the conversion.
See "Can git's .gitattributes treat all files as binary except a few exceptions?".

Git status ignore line endings / identical files / windows & linux environment / dropbox / meld

How do I make
git status
ignore line ending differences?
Background info:
I use randomly Windows and Linux to work on the project. The project is in Dropbox.
I found a lot about how do make git diff ignore line endings. Since i use meld git diff opens meld for each file. And meld says "identical file".
So how do I avoid this. Git should only open meld for changed files.
And git status should not report files as changed if only the file ending is different.
EDIT: Cause:
This happened because of this setting on Windows
core.autocrlf true
So I checked out the working copy on Linux and set core.autocrlf false on Windows.
It would be still nice to know how to make git status ignore different new lines.
Try setting core.autocrlf value like this :
git config --global core.autocrlf true
This answer seems relevant since the OP makes reference to a need for a multi-OS solution. This Github help article details available approaches for handling lines endings cross-OS. There are global and per-repo approaches to managing cross-os line endings.
Global approach
Configure Git line endings handling on Linux or OS X:
git config --global core.autocrlf input
Configure Git line endings handling on Windows:
git config --global core.autocrlf true
Per-repo approach:
In the root of your repo, create a .gitattributes file and define line ending settings for your project files, one line at a time in the following format: path_regex line-ending-settings where line-ending-settings is one of the following:
text
binary (files that Git should not modify line endings for - as this can cause some image types such as PNGs not to render in a browser)
The text value can be configured further to instruct Git on how to handle line endings for matching files:
text - Changes line endings to OS native line endings.
text eol=crlf - Converts line endings to CRLF on checkout.
text eol=lf - Converts line endings to LF on checkout.
text=auto - Sensible default that leaves line handle up to Git's discretion.
Here is the content of a sample .gitattributes file:
# Set the default behavior for all files.
* text=auto
# Normalized and converts to
# native line endings on checkout.
*.c text
*.h text
# Convert to CRLF line endings on checkout.
*.sln text eol=crlf
# Convert to LF line endings on checkout.
*.sh text eol=lf
# Binary files.
*.png binary
*.jpg binary
More on how to refresh your repo after changing line endings settings here. Tldr:
backup your files with Git, delete every file in your repository (except the .git directory), and then restore the files all at once.
Save your current files in Git, so that none of your work is lost.
git add . -u
git commit -m "Saving files before refreshing line endings"
Remove the index and force Git to rescan the working directory.
rm .git/index
Rewrite the Git index to pick up all the new line endings.
git reset
Show the rewritten, normalized files.
In some cases, this is all that needs to be done. Others may need to complete the following additional steps:
git status
Add all your changed files back, and prepare them for a commit. This is your chance to inspect which files, if any, were unchanged.
git add -u
It is perfectly safe to see a lot of messages here that read[s] "warning: CRLF will be replaced by LF in file."
Rewrite the .gitattributes file.
git add .gitattributes
Commit the changes to your repository.
git commit -m "Normalize all the line endings"
Use .gitattributes instead, with the following setting:
# Ignore all differences in line endings
* -crlf
.gitattributes would be found in the same directory as your global .gitconfig. If .gitattributes doesn't exist, add it to that directory. After adding/changing .gitattributes you will have to do a hard reset of the repository in order to successfully apply the changes to existing files.
Issue related to git commands on Windows operating system:
$ git add --all
warning: LF will be replaced by CRLF in ...
The file will have its original line endings in your working directory.
Resolution:
$ git config --global core.autocrlf false
$ git add --all
No any warning messages come up.
I use both windows and linux, but the solution core.autocrlf true didn't help me. I even got nothing changed after git checkout <filename>.
So I use workaround to substitute git status - gitstatus.sh
#!/bin/bash
git status | grep modified | cut -d' ' -f 4 | while read x; do
x1="$(git show HEAD:$x | md5sum | cut -d' ' -f 1 )"
x2="$(cat $x | md5sum | cut -d' ' -f 1 )"
if [ "$x1" != "$x2" ]; then
echo "$x NOT IDENTICAL"
fi
done
I just compare md5sum of a file and its brother at repository.
Example output:
$ ./gitstatus.sh
application/script.php NOT IDENTICAL
application/storage/logs/laravel.log NOT IDENTICAL
I created a script to ignore differences in line endings:
It will display the files which are not added to the commit list and were modified (after ignoring differences in line endings). You can add the argument "add" to add those files to your commit.
#!/usr/bin/perl
# Usage: ./gitdiff.pl [add]
# add : add modified files to git
use warnings;
use strict;
my ($auto_add) = #ARGV;
if(!defined $auto_add) {
$auto_add = "";
}
my #mods = `git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-`;
chomp(#mods);
for my $mod (#mods) {
my $diff = `git diff -b $mod 2>/dev/null`;
if($diff) {
print $mod."\n";
if($auto_add eq "add") {
`git add $mod 2>/dev/null`;
}
}
}
Source code:
https://github.com/lepe/scripts/blob/master/gitdiff.pl
Updates:
fix by evandro777 : When the file has space in filename or directory
In vscode, just stage everything - the files that differ only by line endings should disappear, leaving behind only the files that differ in content. You can then unstage to get to the state you expected.
I've changed +shukshin.ivan script a bit - to ignore windows / linux line ending.
#!/bin/bash
git status | grep modified | cut -d' ' -f 4- | while read x; do
d="$(git --no-pager diff --ignore-cr-at-eol $x)"
if [ "$d" ]; then
echo "$x NOT IDENTICAL"
else
echo "$x IDENTICAL"
# uncomment the next line to undo the line ending changes
# git checkout $x
fi
done

Resources