Hi, On Thu, Feb 1, 2018 at 3:00 PM, Bryan Turner <bturner@xxxxxxxxxxxxx> wrote: > While investigating an issue with rendering conflicts on a pull > request, I noticed that the merge was producing this output (sanitized > for paths) > > $ git merge --no-ff --log -m "Test" 190a25b6e0f32c7b8ccddf8c31e054149dece8b7 > CONFLICT (rename/add): Rename A->B in HEAD. B added in > 190a25b6e0f32c7b8ccddf8c31e054149dece8b7 > Adding as B~190a25b6e0f32c7b8ccddf8c31e054149dece8b7 instead > ... > Auto-merging B > CONFLICT (content): Merge conflicts in B > > (There are several other conflicts listed "between" the two I'm > showing here, various rename/add, add/add and content conflicts, but > I'm trimming those out to focus on the lines that I think are relevant > to my question.) > > This merge produces 2 (or is it 3?) conflicts for the same B path: > - Rename A to B in HEAD, add B in 190a25b > - Content conflicts in B Right, so the merge-base has just one (relevant) file, A. For sake of argument, let's say it's contents is "hello\nworld". One side of history, leading to HEAD, also has one (relevant) file, which was a rename of A->B which also changed its contents to say "hello\nbeautiful\nworld" The other side of history, leading to commit 190a25 has two files. The original A, whose contents has changed to say "hello\namazing\nworld", and a new file called B. When you merge the two, the "hello world" file has been modified differently on the two sides as well as having been renamed from A->B, AND there was a separate file also placed at B on the other side of history which gets in the way. Git resolves the two-files-getting-in-the-way-of-each-other (the rename/add) by moving one of the two out of the way (though it really ought to move both out of the way, but that's a tangent). And it resolves the conflicting content changes in the other B by doing a content merge with conflict markers, giving a file with contents of the form: """ hello <<<<<< beautiful ====== amazing >>>>>> world """ and it treats that B (from the "rename") as more important than other (the "add") which it shows by recording it at B. > I'm still trying to produce a set of steps that will allow a minimal > reproduction, but I thought I'd post to the list just to see if anyone > had any thoughts on how it could happen. Is it a "normal" (albeit > rare) case? Or could it represent some sort of issue in Git's 3-way > merge algorithm (in its behavior or perhaps in how the merge conflicts > are logged)? It is "normal" to get this, and functioning as intended, albeit fairly rare. rename/rename(1to2) and rename/rename(2to1) conflicts could provide very similar situations. rename/add conflicts have three issues I know about[1], but that didn't include the output messages being suboptimal. That might just mean my mind has been warped by reading merge-recursive.c or that I'm too familiar with it, so I don't notice how much it could be improved. If you can think of how to improve the messages, I'm happy to listen, especially since I'm trying to find time to continue my rewrite of merge-recursive. It'd have to apply to other rename cases, as noted above (and, in particular, each side of a rename/rename(1to2) can further be involved in other collisions, such as rename/add or rename/rename(2to1), so it could get hairy quick if the solution isn't simple enough.) [1] https://public-inbox.org/git/20171120221944.15431-6-newren@xxxxxxxxx/; that patch and the others in the series are waiting for the directory rename detection series to progress before I resubmit. Elijah