On 27/07/17 11:36, Phillip Wood wrote:
On 26/07/17 23:12, Junio C Hamano wrote:
Junio C Hamano <gitster@xxxxxxxxx> writes:
Hmph, this is interesting.
"git rebase" does take "--rerere-autoupdate" option from the command
line, and propagates it to a later invocation of "rebase --continue"
by storing the value to $state_dir/allow_rerere_autoupdate file and
reading the value from it. $allow_rerere_autoupdate shell variable
is used to hold the setting.
I'd expect that this variable to be used in invocations of "git am"
in git-rebase--am.sh; but that does not seem to be the case. I
wonder if this was once working but over time we broke the feature
without anybody noticing it, or if the support was added but not
completed and the feature was a no-op from the beginning?
At least in v1.7.0 when doing "rebase -m", the rerere-autoupdate was
plumbed correctly through to the invocation of "git merge" that is
done inside git-rebase.sh. I do not see the same option passed down
to the invocation of "git am", so perhaps nobody cared back then
about rerere during "git rebase" that does not use "git am" backend,
even though "git am" itself were capable of talking the option.
In any case, if you corrected the existing "git rebase" and its
backend so that "--rerere-autoupdate" works as advertised
I've had a quick look and I think it's just a case of adding
'$allow_rerere_autoupdate' to the invocation of 'git am'. 'git am' calls
rerere_clear() when skipping so that doesn't need to go into the shell
script. I'll come up with a test to check it works as I think it does.
I think
you are already 80% there without adding a yet another option, as I
suspect that the most of the need for avoiding "git add" during a
"git rebase" session is during a conflict resolution, and allowing
"rerere" to automatically update the index with auto-resolution will
leave _only_ changes to the paths the end user actually needs to
take a look and manually fix still not in the index.
I'm interested in the 20% as it's about 100% of my rebase conflicts.
I've got rerere enabled but I cannot recall it helping me with a rebase
conflict in the five or six years I've been using git [1]. A lot of my
rebase conflicts come from fixup! commits or reordering things with
rebase -i and generally they're only going to happen once as I don't
apply the same fixup! more than once and if I've rearranged commits the
conflicts are likely to be different in the (possibly unlikely) event I
rearrange them again in the future.
Once I've resolved a conflict I will look at the diff and maybe compile
and run some tests. Then, if I'm happy I'll run 'git rebase --continue',
to me the 'git add' stage doesn't really add anything useful, it's just
an inconvenience.
The other use I have for --autostage is when editing commits with rebase
-i, once I'm happy with the edit I just want to continue and have rebase
amend the commit. I don't feel having to run 'git add' is helpful in
this case.
And from the
workflow point of view, encouraging them to "git add" their manual
resolution after they are satisified with their changes by not doing
"git add" blindly for all changes, like your --autostage" does, is
probably a good thing.
Git allows 'git commit -a' to complete a conflicted merge which I think
is much the same thing as I'm proposing. Also there's nothing to stop a
user accidentally running 'git add' on a path that isn't resolved or
just blindly running 'add -u' before continuing the rebase because they
think they've resolved everything. I guess it is a kind of
convenience/safety trade-off.
In my mind running 'git rebase --continue' is the signal to git that the
conflicts are resolved.
Best Wishes
Phillip
[1] Maybe I've not noticed it helping when rebasing onto an updated
upstream, although if I'm actively changing the rebased commits between
upstream updates the conflicts may well change between updates. Also I
don't tend to get many upstream conflicts with the projects I'm working on.
Thinking about it some more, once a conflict is resolved, the next time
that rewritten commit is rebased onto an updated upstream the same
conflict will not occur as the rewritten commit that's being replayed
does not conflict with the previous upstream - the resolution is baked
into the commit that's being replayed.