git crlf configuration in mixed environment - windows

I'm running a mixed environment, and keep a central, bare repository where I pull and push most of my stuff. This centralized repository runs on Linux, and I check out to Windows XP/7, Mac and Linux. In all repositories I put the following line in my .git/config:
[core]
autocrlf = true
I don't have the flag safecrlf=true anywhere. First time when I modify stuff on my one Windows machine (XP) there is no problem and when I look at the diff, it looks fine. But when I do the same on the other Windows machine (7), all lines are shown as changed but local line endings are \r\n as expected (when checked in a hex editor). The same applies to a MacOSX can. Sometimes I get the feeling that the different systems wrestle on line endings, but I can't be sure (I'm loosing track of all the times I change specific files).
I didn't use to have the autocrlf set, but set the flag many months back. Could that be causing my current problems? Do I need to clone everything again to loose some old baggage? Or are there other things that needs configuring too? I tried git checkout -- . about a million times, but with no success.

You need to set autocrlf to true on each machine you are working on (in global), or for each copy of the repository (in local). The settings of the repo you cloned from are not applied to your local repo.
The other answer is that you have a mixture of line endings in the files in your repo.
A filter on checkout could be setup for each of the source file type to correct their line endings, and on checkin to reset them to the repo standard.

Related

Is "git checkout --patch" incompatible with autocrlf=true?

On my windows machine I'm considering setting autocrlf = true in my .gitconfig. Others on my team have it set this way and we've ended up with a mix of lf & crlf in the repo. I've considered a few options and this seems like the path of least resistance...
One thing I've noticed is that git checkout -p fails with the error patch does not apply when autocrlf = true. If I change it back to false it works as expected.
Is autcrlf = true incompatible with checkout --patch or is do I need to set some other option to get it to work?
Interestingly git add --patch works as expected with autocrlf = true.
Yes, git checkout --patch works properly with line ending translation. The patch almost certainly isn't applying because you have mismatched configuration.
Everybody on your team needs to use the same line ending configuration. core.autocrlf=true isn't an option that one person on a team can enable; everybody needs the same settings. That's because if you have core.autocrlf=false, then you're telling Git that the contents on disk are identical to the contents in the repository. If you're on Windows, that means that you're checking in files with Windows-style line endings (\r\n). If you have a colleague who enables core.autocrlf=true, then you're telling Git that the contents on disk have Windows-style line endings while the contents in the repository have Unix style line endings (\n).
But your colleague has told git a lie, since the repository contents actually have \r\n in them.
A variety of strange things can occur when these settings are mismatched, including things like patches failing to apply.
You should instead:
Set * text=auto in your .gitattributes file. This ensures that everybody working in the repository has the same settings, since the configuration is actually checked in and not something that everybody has to remember to configure properly.
Renormalize the repository, so that the repository contents actually match what you've claimed. You can do this by git add --renormalize . and checking the contents in.
Once you've done this (and everybody has updated your local working folders), your git apply --patch should behave correctly.

Illegal Byte sequence in a file name while checking out git branch

I am using git in cli to change the current branch:
git checkout dev
and it produces:
fatal: cannot create directory at 'app/src/androidTest/java?com': Illegal byte sequence
As answered in this question and this one, I tried:
LC_ALL=C git checkout dev
or
LC_CTYPE=C git checkout dev
but I am getting the same error as shown above.
Running:
git status
shows that some of the files were changed by the checkout, but I am still on the master branch.
How can I remove the file causing the problems or how can I checkout the branch without getting this error?
The locale only affects how things are displayed. If the file name contains a character which isn't allowed by the file system, no amount of locale tweaking can fix that.
I can't think of a way to force a file system to let you create a file which then cannot be used, or a good reason to want to be able to do that.
Probably as a workaround, create a virtualized host with a bare-bones Linux system formatted to permit old-style 8-bit file names (Latin-1 or CP1252 if you can live with the unsavory Windows flavor of that), check out the file there, rename and commit the rename back to git. You still won't be able to check out versions of the source tree from before the rename.
I have found a few files in various github projects that are not compatible with one or another operating system. Files with a ".nul" or ".con" extension are a real pain on windows, for example. It isn't a problem exclusive to git. For example Subversion will abort nastily if it can't restore a file for local naming reasons.
In some cases the file may have been uploaded in error. If that is the case for your own projects it should be possible to use the git tools to list the archive and perform a delete of the file from the archive without actually instancing the file locally.
In other cases perhaps that particular file is not significant, and perhaps can be ignored. Perhaps a test will fail if it is missing?
One trick I have used is to stop the whole folder containing that file from being synced by manually creating the directory path, but for the last element, create an empty file instead of a folder. Of course, now the whole test suite will fail.
When the version control tries to do the checkout, it will simply fail to restore the folder, rather than giving a fatal error.
Of course, that only works if the folder is non-critical, e.g. some test files.
The alternative is to piecemeal check-out all but the problem file, but that can be a tedious sequence of checkouts. But you can use this attack to restore the rest of the folder that you omitted using the above technique. Alternatively, locally drag the files from the zip download if they are non-critical.

TortoiseGit, ignore line endings

I am looking for a way to prevent TortoiseGit from flagging files as changed when they have Unix line endings. It is just tough to check if remote files have changed when you FTP download a folder, they show up as changed often because of the LF version that comes down. I'm on Windows, the repos are CRLF, but as I said when they change on the server they end up as LF.
Right click in that repository, TortoiseGit -> Settings
Turn local AutoCrlf OFF and apply the setting
Extra ref.
Read Dealing with line endings - Per-repository settings,
then try Dealing with line endings - Refreshing a repository after changing line endings
In my case all local files was showing change in newline chars. When I looked closely the 'CRLF' was converted to 'LF'. If I change the LF to CRLF manually, it was not working as in GIT repo it was showing it as difference in file.
I also tried Yue's changes but while clicking on Apply button it was asking me windows hook file, that I do not had.
Then i realized that recently I had installed "cygwin" on my system. I was done using that, so I removed it and restarted system, and all my problems gone.
My answer may help someone in my situation.

Git: Unable to discard changes due to line endings?

"Out of the blue" I've started having this issue with a git repository that I have hosted on GitHub.
Whenever I pull a remote branch to my computer (even on the first clone of the repository) an arbitrary (?) set of files appear as "Changes not staged for commit". I am running on Windows 8.1 and using SourceTree alongside Git Bash as git clients.
An examination of the changes in these files shows that nothing has changed in them, except, maybe, the line endings. I don't know how to view the line endings when diffing so can't be sure.
When I try to "discard" these changes, it simply doesn't work. git reset --hard simply has no effect and the changes remain in place.
Why is this happening? How can I make it go away? :)
PS - When I run git config -l I see core.autocrlf=true appear 3 times in the list.
PPS - I have a .gitattributes file in the root of the repository. Deleting it does not have any effect on the above symptoms. It was first added a few days ago. It's all commented out except for * text=auto in the beginning of the file.
UPDATE:
I've found the minimum steps to reproduce my issue:
I open a file in a text-editor, add a single space somewhere and save it.
The file appears under "Changes not staged for commit" (obviously).
I remove the single space from the file and save it.
The file remains under "Changes not staged for commit" even though both SourceTree's diff and Kdiff3 show that the file is binary equal to its previous version.
Please note that the file in this example had CRLF line endings before I edited it and after I edited it - I don't understand why git insists on marking the file as changed.
UPDATE 2:
Running git diff --raw MyProject/app.config where MyProject.app/config is one of the files marked as changed gives:
:100644 100644 b960510... 0000000... M MyProject/app.config
The fact that the second SHA1 is all zeroes looks like a clue to me - but I don't know what it means.
This is a common problem when you set core.autocrlf after the fact. You can try this procedure from GitHub help. Another easy solution is to just clone a new local copy of the repository, which can also be a good troubleshooting step if you're still having problems.
UPDATE 3: I was able to resolve my issue by removing the .gitattributes file from the root of my repository.
The most likely suspect for having added this file into the repo in the first place is Visual Studio 2013 are per this Microsoft Connect issue.
I still don't understand why having this file (with this core.autocrlf=true in it) caused the behavior that I observed. If anyone has a good explanation, please post it as an answer and I will accept it.
Following the github article on dealing with line endings you can see that setting text=auto on the .gitattributes file tells git to "handle the files in whatever way it thinks is best." Seeing that the rest of the file was commented, and you had a star on text=auto, this was applied on everything. I suppose that in your case, what git thought was best, turned out to be the wrong choice.

Phantom local changes showing in Git

I have a very strange git error here that has me totally at a loss. It's not a major blocker, but it's extremely irritating to work around all the time.
I have a working copy of a repository and, in said working copy, every time I switch from one branch to another Git tells me, after the switch has completed, that I have local modifications. A few more details:
This is on Windows
Git status shows the file(s) as changed (every line as changed, see attached screenshot for an example)
Beyond compare shows no differences; file encoding and line endings are the same, both files exact same number of bytes.
The weird thing: I can't reset the changes, whatever they are. Even deleting the file and then resetting the deletion results in a new file that is supposedly changed.
What could be going on here? I thought that it might be something to do with file attributes, but I have no idea how to check this.
Update:
VonC was correct that it was line endings that were the issue. More specifically if you have core.autocrlf set to true but any files in the repository that were previously committed with Windows line endings then you will see this issue. The reason it's impossible to reset the change is the fact that checking out the file modifies it, since Git works out that your working copy of the file is different to how it would look if you were to commit it now. Confusing, I know.
Anyway, I was able to fix the issue by making one huge commit that set all the line endings in the repository to Unix, which luckily turned out not to be as huge a pain as you might think. I followed the instructions in this post: Trying to fix line-endings with git filter-branch, but having no luck, specifically the answer by Russ Egan, which worked best for me.
Simply make sure to type (once), before the next checkout:
git config --global core.autocrlf false
That will avoid the kind of automatic eol (end-of-line) transformation that this setting (set to true by default with msysgit) does.
.gitattributes files are a better place to declare the files you want to have their eol managed.
See "git replacing LF with CRLF" for more on that setting.
As I originally posted in this question...
I had some phantom changed files that were showing as modified, but were actually identical.
Running this command sometimes works:
(Turns off git's "smart" but often unhelpful line-ending conversions)
git config --global core.autocrlf false
git config --local core.autocrlf false
But in another case I found it was due to a .gitattributes file in the root which had some line-ending settings present, which was trying to apply autocrlf for certain files even when it was turned off. That wasn't actually helpful, so I deleted .gitattributes, committed, and the file no longer showed as modified.

Resources