Subject: Re: bug#69220: [PATCH] smerge-mode: add a function to resolve all conflicts in a file

From: Konstantin Kharlamov <[email-masked]>
Date: Mon, 19 Feb 2024 20:07:41 +0300

On Mon, 2024-02-19 at 15:17 +0300, Konstantin Kharlamov wrote:
> On Mon, 2024-02-19 at 14:03 +0200, Eli Zaretskii wrote:
> > > From: Konstantin Kharlamov <[email-masked]>
> > > Date: Sat, 17 Feb 2024 13:16:14 +0300
> > > 
> > > This implements a feature request from here¹ about having a
> > > function to
> > > resolve all conflicts simultaneously. Although question author
> > > didn't
> > > reply, but either way I think it's a useful functional. I needed
> > > it
> > > so
> > > many times, but before stumbling upon this question I just didn't
> > > know
> > > there are functions `smerge-keep-upper/base/lower`, and so ofc I
> > > never
> > > though of writing a new one that would apply them to all
> > > conflicts.
> > 
> > I use SMerge quite a lot, but never yet had a situation where the
> > same
> > resolution was applicable to all of the conflicts, let alone knew
> > that
> > in advance, before looking at each conflict.
> 
> Well, in Emacs it is allowed to create large commits with many
> functional changes, which I think is why you never saw such
> functional
> to be necessary.
> 
> Offhand I can tell at least two situations where it is needed; both
> imply you have more than one commit on the branch:
> 
> 1. You got a commit that does two different functional changes to a
> hunk. So you want to split it. You do an interactive rebase to the
> previous commit, then do one of the changes and create a commit from
> it. Then you do a `git rebase --continue` and you get conflicts; but
> you know beforehand exactly that you want it to be solved in
> preference
> of the newer commit.¹
> 2. You noted, either yourself or as part of codereview, that one of
> the
> older commits on the branch has a bug; but you know the bug is non-
> existent in newer commits. So you fix it in the older commit, then
> upon
> `git rebase --continue` you again know exactly that you want just the
> newer version.¹

Well, I understand these two points do not sound like something
unsolvable with `git-checkout` theirs/ours options. It's just the
general workflow that I remembered offhand.

I don't remember the distinction down to technical details, only that I
stumbled upon that quite often (which I usually noted because I thought
theirs/ours checkout is gonna work but then it wouldn't; and then I had
to abort everything because I needed conflicts back lol).

I think this happens because git is often quite good in making conflict
as small as possible. So I think if you have case like this: 1. you
modify return value in older commit, 2. You do `git rebase --continue`,
3. you get conflicts because there're unrelated modifications in the
same hunks as `return`s; then you might get conflicts that only contain
lines you just modified and nothing else. So resolving every conflict
becomes trivially choosing "ours" (IIRC, I confuse theirs/ours)
everywhere; but you don't want to `checkout --ours`.

----------------

Incidentally, for me it feels like having the case where you want to
solve *all* conflicts in preference of either side happens more often,
then the case where you want to solve only *only one* conflict in
preference of either side. IOW, if I had to rate by frequency conflict
types I meet during my everyday work, it would be (in order: most
frequent to less frequent):

1. Conflicts requiring manual intervention to take changes from both
sides.
2. Conflicts, where all of them at once may be solved in preference of
theirs or ours.
3. Conflicts where some require manual intervention and some may be
solved in preference of either side.