# Amending a merge commit doesn't update the rerere cache

9 messages from 2010-06-14 to 2010-07-05. Participants: Jay Soffian, Michael J Gruber, Johannes Sixt, Junio C Hamano.
Thread: https://gitlist.dev/t/24112

## Jay Soffian, 2010-06-14 23:04

Subject: Amending a merge commit doesn't update the rerere cache
Message-ID: <AANLkTik50ayTQUnft4oD0Paqf-AuFWxGNdx_zZlHKFPg@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTik50ayTQUnft4oD0Paqf-AuFWxGNdx_zZlHKFPg%40mail.gmail.com

```
Subject says it all, but I'll elaborate.

During the course of testing a merge, I'll sometimes realize there was
a mistake and I'll amend the merge commit. Sadly this doesn't update
the rerere cache. For now I've been doing this:

   mv .git/rr-cache .git/rr-cache.saved &&
   git rerere-train HEAD -1 &&
   rsync -av .git/rr-cache/ .git/rr-cache.saved &&
   rm -rf .git/rr-cache &&
   mv .git/rr-cache.saved .git/rr-cache

Which is quite hackish. I think amending a merge commit should
probably update the rr-cache, but I'm not sure how best to fix this.

Thoughts?

j.

```

## Michael J Gruber, 2010-06-15 06:21

Subject: [PATCH] rerere.txt: Document forget subcommand
Message-ID: <ebd2b2b5bb3352c6204f181416a7a521f8c6abf7.1276582759.git.git@drmicha.warpmail.net>
URL: https://gitlist.dev/e/ebd2b2b5bb3352c6204f181416a7a521f8c6abf7.1276582759.git.git%40drmicha.warpmail.net
In-Reply-To: <AANLkTik50ayTQUnft4oD0Paqf-AuFWxGNdx_zZlHKFPg@mail.gmail.com>

```
dea4562 (rerere forget path: forget recorded resolution, 2009-12-25)
introduced the forget subcommand for rerere.

Document it.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
 Documentation/git-rerere.txt |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index acc220a..a7370d3 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -7,7 +7,7 @@ git-rerere - Reuse recorded resolution of conflicted merges
 
 SYNOPSIS
 --------
-'git rerere' ['clear'|'diff'|'status'|'gc']
+'git rerere' ['clear'|'forget' <pathspec>|'diff'|'status'|'gc']
 
 DESCRIPTION
 -----------
@@ -40,6 +40,10 @@ This resets the metadata used by rerere if a merge resolution is to be
 aborted.  Calling 'git am [--skip|--abort]' or 'git rebase [--skip|--abort]'
 will automatically invoke this command.
 
+'forget' <pathspec>::
+
+This resets the conflict resolutions which rerere has recorded for <pathspec>.
+
 'diff'::
 
 This displays diffs for the current state of the resolution.  It is
-- 
1.7.1.511.gfbed4

```

## Johannes Sixt, 2010-06-15 06:23

Subject: Re: Amending a merge commit doesn't update the rerere cache
Message-ID: <4C171C7B.3060904@viscovery.net>
URL: https://gitlist.dev/e/4C171C7B.3060904%40viscovery.net
In-Reply-To: <AANLkTik50ayTQUnft4oD0Paqf-AuFWxGNdx_zZlHKFPg@mail.gmail.com>

```
Am 6/15/2010 1:04, schrieb Jay Soffian:
> Subject says it all, but I'll elaborate.
> 
> During the course of testing a merge, I'll sometimes realize there was
> a mistake and I'll amend the merge commit. Sadly this doesn't update
> the rerere cache.

There is

	git rerere forget that/conflicted/file

It definitely works as long as the conflict is still recorded in the
index; I'm not sure if it works after you have staged the updated resolution.

-- Hannes

```

## Jay Soffian, 2010-06-15 13:08

Subject: Re: Amending a merge commit doesn't update the rerere cache
Message-ID: <AANLkTimlVyDCc72yirAcL0t0YEWErAT_e0Fadq-WbxNM@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTimlVyDCc72yirAcL0t0YEWErAT_e0Fadq-WbxNM%40mail.gmail.com
In-Reply-To: <4C171C7B.3060904@viscovery.net>

```
On Tue, Jun 15, 2010 at 2:23 AM, Johannes Sixt <j.sixt@viscovery.net> wrote:
> There is
>
>        git rerere forget that/conflicted/file
>
> It definitely works as long as the conflict is still recorded in the
> index; I'm not sure if it works after you have staged the updated resolution.

In fact, I use "rerere forget" as part of a hacked up rerere-train
that I call after I've gotten my merge correct:

---- snip ----
set -- $(git rev-list --parents HEAD -1)
commit=$1; shift
parent1=$1; shift
other_parents="$@"
if test -z "$other_parents"; then
        echo >&2 "HEAD is not a merge commit"
        exit 1
fi

whence=$(git rev-parse --abbrev-ref HEAD)
trap 'git checkout "$whence"' EXIT

git checkout -q "$parent1^0"
if git merge $other_parents; then
        echo "HEAD merges cleanly"
        exit 0
fi

git show -s --pretty=format:"Learning from %h: %s" "$commit"
git rerere forget 2>/dev/null
git checkout -q $commit -- .
git rerere
---- snip ----

I'm still interesting in making commit do the right thing though. In
general, rerere is an underdocumented feature; I guess I'll start
fixing that part first.

(Aside: and the reason I care about rerere being correct is that I
often need to eventually rebase these merges, which is itself a rather
delicate procedure.)

j.

```

## Junio C Hamano, 2010-06-15 16:37

Subject: Re: [PATCH] rerere.txt: Document forget subcommand
Message-ID: <7vr5k86ylg.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vr5k86ylg.fsf%40alter.siamese.dyndns.org
In-Reply-To: <ebd2b2b5bb3352c6204f181416a7a521f8c6abf7.1276582759.git.git@drmicha.warpmail.net>

```
Michael J Gruber <git@drmicha.warpmail.net> writes:

> dea4562 (rerere forget path: forget recorded resolution, 2009-12-25)
> introduced the forget subcommand for rerere.
> ...
> diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
> index acc220a..a7370d3 100644
> --- a/Documentation/git-rerere.txt
> +++ b/Documentation/git-rerere.txt
> @@ -40,6 +40,10 @@ This resets the metadata used by rerere if a merge resolution is to be
>  aborted.  Calling 'git am [--skip|--abort]' or 'git rebase [--skip|--abort]'
>  will automatically invoke this command.
>  
> +'forget' <pathspec>::
> +
> +This resets the conflict resolutions which rerere has recorded for <pathspec>.
> +

This description is not _incorrect_ per-se, but it does not convey one
important aspect of the subcommand; unlike "clear" and "gc", "forget" only
works in the context of the _current_ conflict resolution, just like
"diff" and "status".

Perhaps s/for <pathspec>/for the current conflict in <pathspec>/ would be
a sufficient improvement?

```

## Jay Soffian, 2010-06-15 16:45

Subject: Re: [PATCH] rerere.txt: Document forget subcommand
Message-ID: <AANLkTinfDixTH_l_1quVg68oz4E0AeuuyyOAVrJ2liVz@mail.gmail.com>
URL: https://gitlist.dev/e/AANLkTinfDixTH_l_1quVg68oz4E0AeuuyyOAVrJ2liVz%40mail.gmail.com
In-Reply-To: <7vr5k86ylg.fsf@alter.siamese.dyndns.org>

```
On Tue, Jun 15, 2010 at 12:37 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> +'forget' <pathspec>::
>> +
>> +This resets the conflict resolutions which rerere has recorded for <pathspec>.
>> +
>
> This description is not _incorrect_ per-se, but it does not convey one
> important aspect of the subcommand; unlike "clear" and "gc", "forget" only
> works in the context of the _current_ conflict resolution, just like
> "diff" and "status".
>
> Perhaps s/for <pathspec>/for the current conflict in <pathspec>/ would be
> a sufficient improvement?

Also, pathspec is optional.

j.

```

## Michael J Gruber, 2010-06-16 07:42

Subject: Re: [PATCH] rerere.txt: Document forget subcommand
Message-ID: <4C188060.5000903@drmicha.warpmail.net>
URL: https://gitlist.dev/e/4C188060.5000903%40drmicha.warpmail.net
In-Reply-To: <7vr5k86ylg.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano venit, vidit, dixit 15.06.2010 18:37:
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
>> dea4562 (rerere forget path: forget recorded resolution, 2009-12-25)
>> introduced the forget subcommand for rerere.
>> ...
>> diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
>> index acc220a..a7370d3 100644
>> --- a/Documentation/git-rerere.txt
>> +++ b/Documentation/git-rerere.txt
>> @@ -40,6 +40,10 @@ This resets the metadata used by rerere if a merge resolution is to be
>>  aborted.  Calling 'git am [--skip|--abort]' or 'git rebase [--skip|--abort]'
>>  will automatically invoke this command.
>>  
>> +'forget' <pathspec>::
>> +
>> +This resets the conflict resolutions which rerere has recorded for <pathspec>.
>> +
> 
> This description is not _incorrect_ per-se, but it does not convey one
> important aspect of the subcommand; unlike "clear" and "gc", "forget" only
> works in the context of the _current_ conflict resolution, just like
> "diff" and "status".

Does "current context" mean

- any recorded resolutions for the hunks which are currently recorded as
in in conflict

or

- the resolution which has (just) been recorded for the current conflict?

I'm completely agnostic of the underlying implementation of rerere (as
demonstrated by my questions probably...).

> Perhaps s/for <pathspec>/for the current conflict in <pathspec>/ would be
> a sufficient improvement?

I guess that would mean 2 above?

In any case, rerere forget is not a solution for the original "amend
merge commit and forget previous resolution" question, I guess (I just
happened to note it's undocumented). One would have to redo the merge to
get the conflict info into the index, right?

Michael

```

## Junio C Hamano, 2010-06-16 17:33

Subject: Re: [PATCH] rerere.txt: Document forget subcommand
Message-ID: <7vljaeg9wt.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vljaeg9wt.fsf%40alter.siamese.dyndns.org
In-Reply-To: <4C188060.5000903@drmicha.warpmail.net>

```
Michael J Gruber <git@drmicha.warpmail.net> writes:

> Junio C Hamano venit, vidit, dixit 15.06.2010 18:37:
>> Michael J Gruber <git@drmicha.warpmail.net> writes:
>>> +'forget' <pathspec>::
>>> +
>>> +This resets the conflict resolutions which rerere has recorded for <pathspec>.
>> 
>> This description is not _incorrect_ per-se, but it does not convey one
>> important aspect of the subcommand; unlike "clear" and "gc", "forget" only
>> works in the context of the _current_ conflict resolution, just like
>> "diff" and "status".
>
> Does "current context" mean
>
> - any recorded resolutions for the hunks which are currently recorded as
> in in conflict
>
> or
>
> - the resolution which has (just) been recorded for the current conflict?

The latter.  You can have more than one rerere database entries for the
same path (i.e. merge conflict resolutions for unrelated branches, each of
which changes unrelated things that happen to be in the same path).  The
entries in the rerere database are "when we see a conflict of this shape
(anywhere), the user wants to resolve it this way", indexed by the shape
of the conflict.  There is no "path" recorded in the database.

When "rerere forget" is run, it needs to be told which entry to forget,
and this is done by regenerating the conflict you just had (and possibly
have already resolved, if you are using recent enough git that knows
"resolve undo") using the information in the index, and <pathspec> is used
to limit this set (i.e. when you have more than one path conflicted in the
current merge).

> In any case, rerere forget is not a solution for the original "amend
> merge commit and forget previous resolution" question, I guess (I just
> happened to note it's undocumented). One would have to redo the merge to
> get the conflict info into the index, right?

Once you write the result of a merge out to a tree, the tree does not even
know if there was a conflict.  It does not know how you arrived to that
state in general.  You simply don't have enough information after reading
a tree into your index in order to "amend" it.  When reading a tree that
belongs to a merge commit into the index, we _could_ try to regenerate the
conflicted state and immediately resolve them to the tree's state but I
don't think it is worth the cost and complexity.  Besides, at that point
you do not even know what merge strategy (and which version of that
strategy) was originally used.

```

## Michael J Gruber, 2010-07-05 13:15

Subject: [PATCHv2] rerere.txt: Document forget subcommand
Message-ID: <4d2171a1aeb40321f5956da48f2a36e7709a8a7c.1278333908.git.git@drmicha.warpmail.net>
URL: https://gitlist.dev/e/4d2171a1aeb40321f5956da48f2a36e7709a8a7c.1278333908.git.git%40drmicha.warpmail.net
In-Reply-To: <7vljaeg9wt.fsf@alter.siamese.dyndns.org>

```
dea4562 (rerere forget path: forget recorded resolution, 2009-12-25)
introduced the forget subcommand for rerere.

Document it.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
This somewhat fell under all radars.

v2 takes into account suggestions by Junio and Jay.

 Documentation/git-rerere.txt |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt
index acc220a..db99d47 100644
--- a/Documentation/git-rerere.txt
+++ b/Documentation/git-rerere.txt
@@ -7,7 +7,7 @@ git-rerere - Reuse recorded resolution of conflicted merges
 
 SYNOPSIS
 --------
-'git rerere' ['clear'|'diff'|'status'|'gc']
+'git rerere' ['clear'|'forget' [<pathspec>]|'diff'|'status'|'gc']
 
 DESCRIPTION
 -----------
@@ -40,6 +40,11 @@ This resets the metadata used by rerere if a merge resolution is to be
 aborted.  Calling 'git am [--skip|--abort]' or 'git rebase [--skip|--abort]'
 will automatically invoke this command.
 
+'forget' <pathspec>::
+
+This resets the conflict resolutions which rerere has recorded for the current
+conflict in <pathspec>.  The <pathspec> is optional.
+
 'diff'::
 
 This displays diffs for the current state of the resolution.  It is
-- 
1.7.1.621.g01d76

```
