On Mon, Mar 12 2018, Elijah Newren jotted: > Hi everyone, > > I'd like to change add/add conflict resolution. Currently when such a > conflict occurs (say at ${path}), git unconditionally does a two-way > merge of the two files and sticks the result in the working tree at > ${path}. > > I would like to make it instead first check whether the two files are > similar; if they are, then do the two-way merge, but if they're not, > then instead write the two files out to separate paths (${path}~HEAD > and ${path}~$MERGE, while making sure that ${path} is removed from the > working copy). > > Thoughts? > > I have a patch series[1] with more details and other changes, but > wanted to especially get feedback on this issue even from folks that > didn't have enough time to read the patches or even the cover letter. Does this mean that e.g. in this case of merging two files, one containing "foo" and one containing "bar": ( rm -rf /tmp/test.git && git init /tmp/test.git && cd /tmp/test.git && echo foo >README && git add README && git commit -mfoo && git checkout --orphan trunk && git reset --hard && echo bar >README && git add README && git commit -mbar && git merge --allow-unrelated-histories master; cat README ) That instead of getting: <<<<<<< HEAD bar ======= foo >>>>>>> master I'd now get these split into different files? I'm assuming by similarity you're talking about the same heuristic we apply for git diff -M, i.e. if "moving" a file would consider it removed/added instead of moved you'd want two files instead of the two-way merge. I don't mind this being a configurable option if you want it, but I don't think it should be on by default, reasons: 1) There's lots of cases where we totally screw up the "is this similar?" check, in particular with small files. E.g. let's say you have a config file like 'fs-path "/tmp/git"' and in two branches you change that to 'fs-path "/opt/git"' and 'fs-path "/var/git"'. The rename detection will think this these have nothing to do with each other since they share no common lines, but to a human reader they're really similar, and would make sense in the context of resolving a bigger merge where /{opt,var}/git changes are conflicting. This is not some theoretical concern, there's lots of things that e.g. use small 5-10 line config files to configure some app that because of some combo of indentation changes and changing a couple of lines will make git's rename detection totally give up, but to a human reader they're 95% the same. 2) This will play havoc with already established merge tools on top of git which a lot of users use instead of manually resolving these in vi or whatever. If we made this the default they'd need to to deal with this new state, and even if it's not the default we'll have some confused users wondering why Emacs Ediff or whatever isn't showing the right thing because it isn't supporting this yet. So actually, given that last point in #2 I'm slightly negative on the whole thing, but maybe splitting it into some new format existing tools don't understand is compelling enough to justify the downstream breakage. I don't think we've ever documented the format we leave the tree in after a failed merge as equivalent to plumbing, but for the purposes of tools that build on top of git it really is.