Here’s what I keep reading:
With distributed version control, merges are easy and work fine. So you can actually have a stable branch and a development branch, or create long-lived branches for your QA team where they test things before deployment, or you can create short-lived branches to try out new ideas and see how they work… This is possibly the biggest advance in software development technology in the ten years I’ve been writing articles here. – Joel Spolsky
But this is git. Branches are easy. You should use them. You should use them more than you do. And I’m confident in saying that, because I’ve never yet met anyone (myself included) who branches as often as they should. -Dominic Humphries
I don’t know what brand of crack my esteemed colleagues are smoking, but merge is in fact totally something to worry about. Step into my world…
A .pbxproj file is basically the “This is the project” file for XCode. It’s written in what looks to the untrained eye like a strange superset of JSON. Every time you add or remove any files to the project, this file gets modified by magical closed-source tools. It turns out that for most trivial changes a simple “left, then right” in your diff tool of choice will solve the problem. But that’s every time you merge anything. And may God have mercy on your soul if you’ve mucked with XCode’s organization structure.
It used to be the case that XCode would crash if you did a nontrivial change to this file while it was open. I think they fixed it last year, but you have many generations of Apple developers who say a prayer before merging anything. Also, they continue to invent new and novel ways of holding project metadata that include, at the time of this writing, about four different XML files that sometimes come along for the ride.
So a xib (sometimes called “nib” for historical reasons) is sort of the answer to Microsoft’s XAML (Well, xib came first. Perhaps it’s the question to which XAML is the answer?) It’s a file that describes how the user interface is laid out that gets fed to a compiler. Let’s leave aside the flamewar about whether or not this is a good idea (it gets some play now and again) and focus on the fact that we do have a project and it does use this.
But the key difference with XAML is that nobody really understands the xib format outside of Cupertino. I mean, it’s basically XML, but XML is an alphabet, not a language, and that doesn’t really help. You can probably find some neckbeard who reverse engineered it two versions ago and maybe his knowledge is current, and you can probably guess what is the right thing to do in common cases.
End result: Every time two people nontrivially work on the same screen, a neckbeard is summoned, and people use guess-and-check, the same method they teach fourth-grade math students, to do the merge.
Oh, and by default the system diff tool does this weird preprocess step before it displays the file, I guess to try and give you better-than-zero insight into what actually changed. Result: can’t choose hunks.
So here’s how I envision this one being invented:
Engineer 1: “You know what we should do? You know those xib files that cause merge conflicts every time two people touch the same screen?”
Engineer 2: “Yeah?”
Engineer 1: “I think we should announce, as a headline feature of iOS 5, that now you can pack all of those into one file, so that every change to any UI anywhere conflicts with every other change to every UI everywhere.”
Engineer 2: “Great idea!”
This is essentially Core Data’s version of xib, that changes every time you update any data model. The good news is, it is sort of easier to understand the contents of the file even if you’re not a neckbeard, so it is sort of easier to merge.
The bad news is, there is a nasty bug in XCode that causes the incremental compiler to re-use old versions of the data model in your builds. So whenever you muck with this file outside of XCode, you must always remember to clean build, or you will keep reporting bugs to the data model people that don’t really exist.
So I don’t know about you, but I end up with a lot of stuff that I need for unit tests. For example, I have a test suite that runs on a fairly large dataset. This dataset is frozen in a SQL blob and checked in to the repository so that mere mortals can run the test suite. Every time I change my data schema, I also have to refactor that blob so that the tests pass. And there’s no way to merge sample data.
Or, I do isolated client/server testing, and I have a blob somewhere that stores the responses of a server that I recorded once upon a time. If the server changes behavior for whatever reason, I have to update the blob. Maybe I do it on two branches, and they don’t merge cleanly.
Branching and merging is not “all that easy”. Maybe you’re not an iOS developer and so 4/5 of my examples don’t apply to you, but even 1/5 is a barrier to clean merges, unless you don’t have a comprehensive test suite. (And you do…. right? Right?)
In theory, we can do something about this. Git has this thing called “merge driver” which lets you inject custom merge behavior for particular file formats. In theory Apple (or heck, ordinary people) could write such a thing, as far as the reverse engineering allows. In practice, nobody has even bothered to write a merge driver for XHTML, so that should give you some idea of what’s been done here. There’s a thing that could probably be adapted for XML, but it seems to have been abandoned.
If you want to claim that the merge problem is solved, you have to first have merge drivers for all the formats. As far as I can tell, we have merge drivers only for plain text.
 One of the few people who has looked at the problem seriously has concluded: “So, overall, it looks like this is a much harder problem than I initially thought.”