Consider two commits: one adds file A, and the other adds file B.  These 
commits don't conflict; you can merge them with no problem.

But if the two commits instead add submodules A and B, and you try to merge, 
you'll likely get a conflict in .gitmodules.  This seems wrong; .gitmodules 
happens to be a plain text file as an implementation detail, but in terms of 
interpretation, it is more like a map of maps (name1 -> {path -> "...", url -> 
"..."}, name2 -> ...).  

We (Two Sigma) keep our .gitmodules file in alphabetical order (so we don't use 
git submodule add -- our .gitmodules file is instead generated by some more 
complicated offline process).  But even for ordinary .gitmodules files, order 
is not important so long as it's consistent.

I could set my .gitattributes for the .gitmodules file to use a custom merge 
driver. But: (a) I don't see an off-the-shelf one that does what I want 
("union" happens to work in the add/add case, but not in the add/remove case or 
other cases) and (b) I would have to rewrite my whole history in order to have 
the .gitmodules file exist at every commit (or find a way to get 
.git/info/attributes into each of my users' clones) and (c) this should work 
correctly without customization; Git already treats the .gitmodules file as 
special for commands like "status"; there's no reason it shouldn't do so for 
merge and rebase.

I'm not sure I'll necessarily have time to implement this -- for our use case ( 
http://github.com/twosigma/git-meta ), we might be able to get away with doing 
it in JS, and using something like 
https://github.com/mirkokiefer/diff-merge-patch#sets .  But if I did have time, 
do others agree that it would be reasonable to special-case this file?  
(Naturally, before doing the merge, we would check that the file was in fact 
parseable as a git config file; merging two changed gitmodules files of which 
either is unparseable would fall back to merging as text). 

Reply via email to