Subject: bug#20292: 24.5; Saving Git-controlled file with merge conflicts after "stash pop" stages the file

From: Dmitry Gutov <[email-masked]>
Date: Wed, 16 Nov 2016 02:25:32 +0200

Hi Junio,

Sorry for the late reply. Too bad neither of your emails were recorded 
in the bug report thread 
(https://debbugs.gnu.org/cgi/bugreport.cgi?bug=20292).

Maybe it would be better if you file a separate bug report.

On 27.10.2016 20:20, Junio C Hamano wrote:

> The way Git is designed to be used is for the user to edit the
> latter to come up with a conflict resolution in the working tree,
> then add that result to the index, after the user is satisfied with
> it, before continuing (typically, but not necessarily, to record the
> result with "git commit").
>
> Now, what about the cleanly automerged paths?  They are added to the
> index and this is by design.  You can see why this is necessary by
> doing:

Thank you for the explanation. It does make sense now, but that does not 
necessarily mean that we should change what Emacs does about the conflicts.

You see, the change in question is in vc-git, which is part of our VC 
package, which does not support every nifty feature of each VCS it 
handles, and instead tries to provide a unified UI to the whole bunch of 
them. In a lot of cases that means that we exchange power for simplicity.

And while we might be happier with a more full-featured solution for 
dealing with conflicts (a new, better visualization, more controls), we 
don't have that now, and vc-git-resolve-conflicts is the faster, simple 
alternative we have come up with for now.

>  - But before doing "git add" to tell Git that you are done with
>    these paths, run "git diff" (no other parameters).  You may have
>    to (setq vc-git-resolve-conflicts nil) for that
>
> You will notice that this invocation of "git diff" show concisely
> how the result of your conflict resolution differs from either of
> the branch.  This is used by Git users as one of the final step of
> verification before telling Git "I now am done with the conflict in
> this path and resolution is good" by issuing "git add" for the path.
>
> You will also notice that this invocation of "git diff" does not
> clutter with changes that have been auto-merged cleanly.  At this
> step of the workflow to resolve conflicts, the user is concentrating
> on the paths that had conflicts, and it is crucial that cleanly
> auto-merged paths do not get in the way.  The user can still view
> the overall picture by asking "git diff HEAD" (to see both
> automerged result and hand-resolved result, the latter of which may
> or may not have been added to the index) and "git diff --cached" (to
> see automerged result and hand-resolved and then "git add"'ed
> result).
>
> So, there is no "Bad news, everybody!" in the behaviour you
> observed.

You have quoted a fairly early message in that bug discussion. Later on, 
we have reached a solution that seems to have satisfied all 
participants. Although it still does the automatic 'git add' call which 
you seems to consider the main problem.

>> What shall we do? Unstage the automatically-staged files? Revert the
>> changes from this bug? It seems Git really wants the changes staged
>> after the conflict resolution.
>
> I do not know what you thought you can achieve by "unstage the
> auto-merged paths?" here, but perhaps you were expecting "git diff"
> (no arguments) would be the way to view all the changes that a mergy
> operation with conflicted states brought in?

Not really. We get the "unstage the automatically-staged files" effect 
by calling "git reset" when the user has made an explicit configuration 
to do that and there's no ".git/MERGE_HEAD" (see the definition of 
vc-git-resolve-when-done).

To put it simply, we wanted to be able to easily resolve the merge 
conflict after e.g. 'git stash pop' without having to additionally 
interact with Git outside of Emacs. The current behavior is a compromise 
that allows us to achieve that. It also mirrors a similar feature in our 
Bazaar VC backend (which certain developers have grown accustomed to).

> If that (i.e. "view
> all the changes") was what you wanted to achieve, then neither
> "unstage the auto-merged paths" nor "automatically 'git add' upon
> saving the buffer" is a good solution.
>
> I was told by somebody that the message I am responding to
> eventually resulted in vc-git-resolve-conflicts that defaults to
> true in Emacs 25.1, which lead to "automatically 'git add' upon
> saving the buffer".  I think this variable and its default is a big
> disservice to Git users' whose daily work involves lots of conflict
> resolutions in mergy operations.

The ability to 'git diff' which you have described seems fairly obscure 
to me and the majority of Emacs/Git users, so even if we make 
vc-git-resolve-conflicts default to nil, it's unlikely that the majority 
of users will really benefit from that.

You, as a core Git developer, represent the informed minority, and as 
such, it's probably not too much to expect that you and the others can 
customize vc-git-resolve-conflicts to nil without much trouble.

That said, I was not the one to add this variable, and though so far I 
have found it useful enough, I wouldn't miss it too much either.

On the other hand, we haven't received any bug reports about it so far, 
so maybe most users either don't notice the new behavior, or have found 
it handy.

Best regards,
Dmitry.