But there are scenarios in which this avoids tedious human merges. Consider that I'm applying a series of patches which make changes in a file and later on walk those changes back, and run into a merge conflict there. In Git, I could squash those changes to avoid dealing with the conflict, but then I've lost history. I could apply the changes, skipping the relevant patches, but if those patches still contained useful work elsewhere, then I'd have to go in and resolve those problems manually.
In contrast, this same scenario in Pijul and Anu would just trivially work in a way that didn't produce conflicts. I would apply the sequence of patches, and one patch would produce a conflict… but because they can keep doing work in the presence of conflicts, then they could keep applying subsequent patches and apply the patches which walk back the changes, and in that resolve the conflict automatically, but unlike the Git approach where I flattened the changes first, I would still have the full commit history associated with that sequence.
Now, that doesn't mean that Pijul or Anu will automatically fix all merges. If you have two separate code edits to reconcile, you might still need a human in the loop to reconcile them. But the fact that they can keep making changes in the presence of conflicts allows them to avoid a certain kind of "busywork" that comes with managing git history.
I don't think it is really true that git requires you to fix conflicts before continuing. There are strategies that can let you emulate deferred merging. I rarely let merging hold me back.
If I don't have time to merge into master, just do git push server master:synced/master.
I port/test a project to a new OS. I run into a bunch of issues, like linkers, environments, etc. that are broken that I need to fix. I try and make clean commits tackling one issue at a time, so we get 1 commit for the linker issues, 1 for the docs, 1 for the environment, etc. eventually I have 5 commits of fixes.
These fixes are all orthogonal, so ideally I want to make separate PRs and separate reviews for them. But locally they're all tied together (in chronological order), since I need all of them there to continue development.
In git I can either open 1 big PR including all fixes at once (annoying) or I can make a PR for one commit, wait until it's merged, then PR the next, etc. The only way to get them nicely separate is if I take all those 5 commits, rebase each of them onto master in its own branch and PR those 5 branches. But that ruins my ability to work locally.
The associativity of (non-conflicting) patches in a patch based VCS like Anu/Pijul means that this "ordering" of patches doesn't exist. I have 5 patches you don't, I can PR each of them independently without needing to manipulate history or anything, because fundamentally the patches aren't related and therefore there's no reason for an ordering like the git DAG forces upon you.
Of course this is a fairly niche (but hopefully concrete enough) example of how this enforced ordering of commits can actively harm workflows/collaboration.
Once the PR (possibly with some changes still) is approved and merged, I would rebase my "work" branch on top of the updated master. Since it was an orthogonal commit, you'll typically see that the merged work just disappears from your branch during the rebase. If it really was orthogonal work, you'll not have any conflicts.
This is an approach I've used whenever I need to work on something that depends on other work that was not merged yet. You have a work branch that includes all the work, since you depend on it, but you want to offer smaller pieces as PR to make the review process more efficient.
(He means on his private computer)
That is incorrect and is not a conflict.
> You can think of this as subtracting older from yours and adding the result to mine, or as merging into mine the changes that would turn older into yours.
The point stands: taking history in account is unconvincing, as it assumes intent where none is explicitly given. In the example, if the top branch had a single commit, AB => ABGAB, then there is no way to reliably infer that A 'intended' [+ABG]AB, vs. AB[+GAB]. Even with the given history, maybe the author of the top branch really intended AB => AB[+GAB], but made an error, corrected in the 2nd commit. The problem is fundamentally ambiguous. We can argue which of the diff3 or anu/pijul heuristics are better. In practice I suspect the difference is not that large.
For completeness, here's a guess of what diff3 does, assuming merging top into bottom, following https://blog.jcoglan.com/2017/05/08/merging-with-diff3.
[bottom] => A [+X] B
[top] => AB [+GAB]
B O T
A A A
+X
B B B
+G
+A
+B
Resulting in A[+X]B[+GAB] without conflicts.Then that example you link means that you should stop using 3-way merge / git / svn / mercurial.
Git definitely could be much smart about merge conflicts, but it's a hard research problem so I'm not surprised it isn't.