{"thread":{"id":"56922","subject":"Generalization of diff and merge","startedAt":"2021-11-17T07:46:04Z","lastAt":"2021-11-17T07:46:04Z","messageCount":1,"participants":["Martin von Zweigbergk"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"441409","messageId":"CANiSa6hKPO1toFu-3sM00zj_QbeFWJFE=aEZEjYoW7wq5rPhXQ@mail.gmail.com","threadId":"56922","inReplyTo":null,"subject":"Generalization of diff and merge","fromName":"Martin von Zweigbergk","fromEmail":"martinvonz@gmail.com","sentAt":"2021-11-17T07:45:49Z","receivedAt":"2021-11-17T07:46:04Z","isPatch":false,"sender":{"key":"martinvonz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/891642?v=4"},"body":"Hi,\n\nSomething I'm currently working on at work reminded me of an idea I\nhad a while ago, which I thought may be useful to the Git project.\n\nThe idea is simply that diffs and merges can be viewed as special\ncases of generalized N-way diffs. This N-way diff function takes an\narbitrary number of inputs and returns a list of matching and\nnon-matching hunks, where the non-matching hunks have the same number\nof parts as there were number of inputs. To get a diff, you pass in\ntwo inputs and interpret the first part of non-matching hunks as the\n\"before\" side and the second part as \"after\" (assuming that's the\norder you passed them in, of course). Similarly, to get a normal 3-way\nmerge, you pass in three inputs (base, left, and right) and interpret\nthe parts of the non-matching hunks accordingly. See the tests in [1]\nfor some examples.\n\nOne advantage of doing it this way is that the merge algorithm becomes\nconsistent with the diff algorithm, so the user won't see conflicts\nwhere the conflicting hunks are in different places than they would\nappear in diff output. This is probably not much of a problem in\npractice.\n\nAnother advantage that I'm not sure matters in the Git project is that\nthe generalization can help render conflicts from octopus merges.\n\nSorry if this is an old idea. The fact that there's `git diff\n--histogram` but no `git merge --histogram` made me think it's not. Or\nmaybe there are simply good reasons to not do the generalization?\n\n[1] https://github.com/martinvonz/jj/commit/987aecc749f82c55cb3481f79680552040f7cf13\n"}]}