Avoid JSON file merge conflicts
I run into JSON file merge conflicts almost every day, and a shocking percentage of the time it’s due to me and another person attempting to add a new line at the end of the file. It’s incredibly frustrating, and adds a considerable amount of friction to rebases given how much disruption the conflict causes relative to how small the issue is.
There are two systemic fixes you could employ for this problem.
JSON5 is a JSON superset that supports trailing commas, but switching from JSON to JSON5 is about as difficult as switching to any other file format. The more tools at play in your repository, the more toil you’re in for.
The other option is to use a custom Git merge driver such as git-json-merge
. This is actually a lot easier to do than it sounds, but it does mean adding an additional tool to your tech stack. I think there’s value in keeping things simple and taking low-code approaches where possible. The less things you need to think about, the better.
The low-code solution here is to add a sentinel value at the bottom of your file. This sentinel value will always be at the bottom of the file, which means you won’t run into merge conflicts from someone else adding a new line at the bottom in parallel to you. From the perspective of git merge
, you’re both just adding a single atomic line to the file.
{ "valueOne": "one", "valueTwo": "two", "ADD_ABOVE_HERE_TO_AVOID_MERGE_CONFLICTS": ""}
The reason why you run into issues otherwise is because you aren’t just adding a value to the end of the file—you’re also modifying what was previously the final line:
3c3,4< "valueTwo": "two"---> "valueTwo": "two",> "valueThree": "three"
In contrast, adding a line to the middle of the file results in a diff for only that one line. Git can easily resolve multiple diffs like this—if it couldn’t, you’d have merge conflicts every single time you merged anything at all.
3a4> "valueThree": "three",
I found this trick inside the cal.com codebase and thought it was too good not to share.