LESS compiling and the version control merging problem

We run a lot of projects at work and increasingly over the last few years we've been using LESS to create the CSS on them. While this is great for us front end developers, it has thrown up a surprising problem for those who are responsible for actioning pull requests through git. Here's some thoughts on a very specific problem.

The problem

A feature branch has been created and worked on (let's call it feature/custard), and a pull request issued back to the main branch (e.g. develop). Unfortunately, there's a conflict between a CSS file in develop and the same CSS file in feature/custard.

The reason

Where a project uses LESS for CSS generation, apps used to compile the LESS usually minify the outputted CSS. The result of this is a single line file, which naturally will cause a conflict in git because git only deals with files on a line by line basis. Essentially the merger has to choose between keeping the CSS file on develop or going with the one from feature/custard.

The solution

Always accept the newest CSS file, in this case from the incoming branch, i.e. feature/custard. The actual changes to the styles are still safely in the LESS files, which are all multi-line, so any conflicts have likely already been sorted out anyway.

If in doubt you can always action the pull request and then recompile the CSS file yourself on the develop branch from the now merged LESS files, but it's far simpler to just accept the CSS file from the incoming branch. I think this problem will only occur if merges are done manually through the command line, as github normally refuses to action a pull request until the conflict is sorted out on the branch.

Another possibility

Another option is to not put the CSS files in the repo at all - simply drop a .gitignore into the CSS directory, and let developers and build scripts compile it themselves. Of course, this completely side steps this whole problem and is a viable solution, but it can add an extra headache. I was working on a project recently that used this approach, which was fine until I was asked to build a new page on the site that had to be responsive, while keeping the rest of the site as it was. Suddenly I found myself having to write responsive styles out into a separate stylesheet, that would only be included on the page that needed it. Then I needed to use a plugin on that page that came with its own CSS, it turned out another page on the site really needed a separate stylesheet... and before I knew it the number of CSS files had jumped from one to five.

Of course, there's nothing stopping that strategy from working with five CSS files instead of one - only that build scripts need to be updated and specific instructions need to be included for all developers on how to compile the increasingly complex LESS. You have to weigh up the relative effort. And that documentation I mentioned should be done regardless.

One more reason why this is a headache is the ongoing nature of LESS.js. Prior to version 1.3 or thereabouts, a specific syntax for performing loops was required, a sort of cludge to make LESS understand it. Now we're at - what, version 1.8 - that has all changed, so if you're running an old compiler on new code, or a new compiler on old code, and your compiler is built into different servers for deployment - well, it can all get a bit much. And who knows what changes will come with the next version of LESS.js? Hopefully nothing as major, but you never know.

Our decision is that we're going to try keeping the CSS in the repo and advising anyone who merges a pull request of this issue - and we'll see how that goes.


Having thought about this a little more, I'd like to re-emphasise what the best solution to this problem is - merge the branches then compile the LESS again from the result. This works for all situations but particularly if there are multiple merges to be done.


This article is tagged with