Subject: Re: [PATCH] rerere: record (or avoid misrecording) resolved, skipped or aborted rebase/am

From: Junio C Hamano <[email-masked]>
Date: Sat, 09 Dec 2006 12:08:49 -0800

I looked at your previous 5-patch series but will replace with
this updated 2-patch series.

The rerere command started its life as a mere helper for
Porcelains, but with 'status' and 'diff', you are making it
somewhat Porcelain-ish.  I still have not decided myself, but I
think we probably would want to treat this as a Porcelain and
give a bit of usability to it, so what I've committed has two
changes from your version:

 (1) 'diff' without @ARGV defaults to '-u';
 (2) running rerere with unknown sub command die()s instead of
     silently exiting with 0.

The difference between your previous 5-patch series and this
round raises an interesting issue.

You used to have a safety valve in git-commit to prevent users
from running it while rebase/am is in progress, which I imagine
would be a common mistake.

There are three commands in git suite that a user would use to
eventually make new commits, out of something other than what
was edited and prepared in the working tree, that can stop in
the middle.

 (1) git-am is used to make new commits from e-mailed patches,
     and stops in the middle when a patch does not apply.
     "git-am --resolved/--skip" are the ways to continue.

 (2) git-rebase is used to rewrite the history of a branch, and
     stops in the middle when a patch does not apply or merge
     conflicts.  "git-rebase --continue/--skip/--abort" are
     possible exits [*1*].

 (3) git-pull/git-merge are used to make merge commits with
     another branch, and stops in the middle when it conflicts.
     Possible exits are "git commit" or "git reset".

Now, I am not going to propose to fix this inconsistency and
forbid use of "git commit" to resolve "git-merge" (instead, the
user would say "git-merge --resolved/--abort").  As the workflow
goes, these are very different operations and the user is often
well aware which workflow is in progress; having different
commands for different exit route is fine.

But in order to implement the safety valve like you did cleanly,
we should first have an enumeration of states (the above is a
subset --- there is the "base state" in which you are working
towards a commit based on HEAD, which is obviously concluded
with a "git commit", and "bisect in progress") and make it easy
for commands to communicate what state the working tree is in.
That would also help 'git-explain'.

[Footnote]

*1* Resuming rebase was much worse before Sean updated it with
commit 031321c6 to hide that it uses git-am as its backend,
which is purely its implementation detail.