- A Concurrent Affair - https://www.concurrentaffair.org -

Cygwin, Subversion and End of Lines

I got myself into a bit of a problem when I tried to set the automatic end-of-line style property [1] for our text files in Subversion. I wanted to use “native”, because that should automatically convert all line endings to LF (“\n”) on Unix and Mac, and to CR LF (“\r\n”) on Windows.

This seemed to work, but unfortunately the language level tests started breaking. It was pretty clear that this had to be a line ending issue. I couldn’t figure out why, though, and I went back and forth and changed the eol-style, ran dos2unix or unix2dos, and because the failures were only appearing after an update or checkout on another system, all of this went into the repository. All in all, it took me from revision 5144 [2] to revision 5163 [3] to get this right. This is shameful.

In retrospect, I should have done this in a branch, but svn was behaving very strangely, and I was worried that I might get it to work in the branch, but then something would go wrong when copying the files back into the trunk. I think there were two things that confused me:

  1. On Windows (or perhaps on Cygwin), Subversion seems to be line-ending insensitive. I can take a file that had Unix line endings, run unix2dos on it, the file had changed, but Subversion would not list it as modified.
  2. On Cygwin, Subversion’s “native” line ending is not the Windows default of CR LF, but LF, just like on Unix systems. That meant that the files with the “expected” outcome still contained LF line endings, but the files we were generating contained CR LF line endings. This is not well documented.

I was close to forcing LF line endings everywhere, but then decided to stick with “native”. If someone actually has a non-Cygwin Windows Subversion client, this may work, and I had to make the unit tests line ending-insensitive anyway.

There was another issue that gave me a hard time for an hour or so: The unit tests use some class files [4] and make sure that they are newer than the source files. I had touched the source files when I changed the line endings, but the class files had not been recompiled. This caused the a couple of unit tests to fail with a nondescript error message. I had to trace the execution of the test to get to the following line to understand the problem:

if (sourceFile.lastModified() > classModTime) {

As a hack, I just Unix-touch the class files to give them a more recent time stamp. I tried to recompile the class files, but that wasn’t possible:

  1. Some of the class files (B.class, Doh.class, TestWeirdStuff.class) don’t have any associated source (it’s missing).
  2. Wow.dj0 contains the public keyword, which is not permitted in the elementary level.
  3. The classes Tom.dj1 and Jerry.dj1 contain a cyclic inheritance graph, so they cannot be compiled, yet their class files exist.

I kept the class files. I didn’t want to re-engineer or understand the unit tests more than I had to. Considering that I had another sudden failure [5] with the unit tests a few weeks ago, I don’t think they are well engineered.

As a side note: I love bash. I don’t know if it’s actually helping or hurting me (kind of like LaTeX), but writing something like this is cool every time:

find . -type f -not -path "\*.svn\*"|xargs -n 1 -I {} -i bash -c 'if [ "`svn propget svn:eol-style {}`" == "LF" ]; then echo {}; fi'| xargs -n 1 dos2unix

Or perhaps a Unix guru out there has a better way to run dos2unix on all files that have been marked with the “LF” end-of-line style property in Subversion?

[6] [7]Share [8]