In my opinion, the following configuration should have been the default with Git:
git config --global rerere.enabled true
git config --global rerere.autoUpdate true
The `enabled` part means: transparently record all resolutions in a database, and re-apply them whenever bumping into the same conflict with the same pair of files in the future.The `autoUpdate` part means: every time you finish re-applying a recorded resolution, please `git add` the result automatically for me so I don’t have to look for a "conflict" that’s actually no longer there.
I don’t see how that is guesswork. My impression is that rerere is perfectly deterministic, and only repeat things the user has done before.
The downside is: once the user has manually created a faulty resolution, then rerere will possibly replay that faulty resolution.
That’s how things can go wrong, and I see how one might blame that failure on rerere itself. And I think the blame not entirely unjustified, because rerere could do a much better job in explaining how it interacts with certain scenarios. For example, let’s say I’m aborting a rebase. Will rerere roll back the resolutions it recorded? I honestly don’t know. The manpage vaguely claims that it will, but I’ve been unable to reproduce it.
I wish rerere made more transparent how it interacts with `--abort`. Just printing an informational line would already go a long way. I also feel a command like `git rerere log`, which would print the recent activity of the `rerere` database, might help with that.
Really? One new added line, and one delete/add two lines above it.
it usually works fine, it really does, but when it messes up, it really messes up big time. As long as it doesn't create a conflict, you just shrug and move on, but when it does create a conflict, holy-moley!
But no, people always seem to insist on that linear history is the only concern that matters, explicitly delete the history, and then wonder why Git is so annoying and easy to screw up.
Maybe Git should have locked rebase behind a feature flag of some kind. `git pull --rebase` should certainly never have been added.
There are many reasons why linear history is important. Rather than saying that "you shouldn't want to do that", I'd prefer it if the tools people use were fixed to better serve the things people actually want to do.
A merge would only make sure that I don't need to resolve the same conflict multiple times. It wouldn't result in the conflicts not being generated in the first place, or them being saner. The only difference in conflict resolution between rebasing and merging is that the sides are flipped (what's shown on left in rebase, is on the right in merge, and vice-versa). Which doesn't address the second issue I listed: conflicts are not only repeated, but the conflicts themselves are pretty crazy. In my example, often-times C would never even touch files which were detected as having conflicting changes with A or B. It was pretty absurd that I would have a 3-line change in C, several hundred-line changes in A and B, yet the biggest conflicts would be triggered when rebasing C on top of B, and those would be in files C did not touch. Other times diffs in conflicts would have most of the lines added and removed actually identical, with only a couple in the middle different. Why would git mark them as conflicting, is beyond me. And then there was the issue of git not detecting conflicts, when it should have, instead merging changes in a way that broke source code. None of those issues is better handled by merging than by rebasing. Most of them however have pretty good solutions in a patch-based version control system, as opposed to snapshot-based like git (conflicts in files which weren't changed? not going to happen). An even better solution would be binary formats with domain-specific merge logic, like the one in KeePassXC.
No, you just add it at the end of the commit chain?
> And rightly so: when I look at the master branch, I don't want to see random corrections someone made during review, they're just irrelevant once the reviewed changes are merged.
git log actually has the --first-parent for this, which hides all of the commits that were merged into the branch, without destroying the history when you try to go back and try to understand why the choices were made. The idealized version of history created by constant rebasing serves neither purpose.
> Rather than saying that "you shouldn't want to do that", I'd prefer it if the tools people use were fixed to better serve the things people actually want to do.
Agreed, tools that cope poorly with merges should be fixed, rather than forcing people to hack around it by rebasing.
> None of those issues is better handled by merging than by rebasing.
Not quite, rebasing generates more false positives, since it tries to merge every intermediate commit instead of only looking at the end states and the common ancestor.
Pijul doesn't, by the way, the diff algorithm is customisable. I wrote one industrial application of Pijul that uses spaces as breaks, and semantics-aware breaking is totally doable.
From what I've read, Pijul should fix at least the problem of needing to resolve the same conflicts multiple times over and over again. However, I feel that version control focused on text breaks, because the merging algorithm doesn't know anything about the semantics of what's represented in text. So yes, I'd say that version control in more areas would be nice, but one based on binary formats understood by version control. One glimpse of that may be KeePassXC, which can merge password databases and has never done it wrong in my experience.