15 Feb 2018

When does running git clone give a dirty working directory?

(Half Relevant) Back Story

I recently changed laptops at work. The change was more involved than copying files from one machine to another as the switch was also in terms of operating system, from macOS to Windows 10. No bother though, most of the tools I’m using are cross-platform and the majority of the development work I do takes place inside CentOS VMs.

I started working on a new programming task and needed to make an edit to some code in one of our main repos. This was the first time I’d used this repo on the new machine. This is also where things started to get strange. Here is a super accurate reenactment…

Getting Weird

Strange! The clone did not give me a clean checkout. I was multi-tasking between a few different terminal windows at the time and wondered if that was the reason for the strangeness, maybe a misplaced command? I ran git checkout -- foo.js but git status still showed a dirty working directory.

Investigating

Running git diff shows the whole file changing. This is classic for a line ending change. Plus we even get a warning in the terminal that line endings are the cause for the diff. (Aside, for visual confirmation you can use git diff -R, which does show the line endings plus other bits of whitespace). Sure enough, the original file has Windows line endings and the new version has Unix line endings.

I assumed I’d got some weird configuration issue going on and started checking for the usual core.autocrlf settings. No such settings were in use though, so what was git doing?

The .gitattributes File

A quick scan of recent commits on the repo revealed the addition of a file called .gitattributes. Opening the file, there was only one line that wasn’t a comment. The attribute line in question was * text=auto. Commenting this out and running git status immediately resolved the issue, showing the only changed file as .gitattributes from the edit we just made.

So what does * text=auto do? Its purpose is normalizing the line endings of files in the repo. The setting is actually very fine grain. The * is a pattern match, much like you might use in a .gitignore file. The docs are an interesting read with good examples if you’ve got a repo where you need to normailze the line endings. For this repo we’ve left it off for now. And with that mystery solved, the world of development starts to makes sense again.

Dev Git SysAdmin
Back to posts