rerere: handle leftover rr-cache/$ID directory and postimage files
If by some accident there is only $GIT_DIR/rr-cache/$ID directory existed, we wouldn't have recorded a preimage for a conflict that is newly encountered, which would mean after a manual resolution, we wouldn't have recorded it by storing the postimage, because the logic used to be "if there is no rr-cache/$ID directory, then we are the first so record the preimage". Instead, record preimage if we do not have one. In addition, if there is only $GIT_DIR/rr-cache/$ID/postimage without corresponding preimage, we would have tried to call into merge() and punted. These would have been a situation frustratingly hard to recover from. Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
2c7929b133
commit
05dd9f139d
42
rerere.c
42
rerere.c
@ -117,7 +117,9 @@ static struct rerere_dir *find_rerere_dir(const char *hex)
|
||||
|
||||
static int has_rerere_resolution(const struct rerere_id *id)
|
||||
{
|
||||
return (id->collection->status & RR_HAS_POSTIMAGE);
|
||||
const int both = RR_HAS_POSTIMAGE|RR_HAS_PREIMAGE;
|
||||
|
||||
return ((id->collection->status & both) == both);
|
||||
}
|
||||
|
||||
static struct rerere_id *new_rerere_id_hex(char *hex)
|
||||
@ -806,24 +808,30 @@ static int do_plain_rerere(struct string_list *rr, int fd)
|
||||
string_list_insert(rr, path)->util = id;
|
||||
|
||||
/*
|
||||
* If the directory does not exist, create
|
||||
* it. mkdir_in_gitdir() will fail with
|
||||
* EEXIST if there already is one.
|
||||
*
|
||||
* NEEDSWORK: make sure "gc" does not remove
|
||||
* preimage without removing the directory.
|
||||
* Ensure that the directory exists.
|
||||
* mkdir_in_gitdir() will fail with EEXIST if there
|
||||
* already is one.
|
||||
*/
|
||||
if (mkdir_in_gitdir(rerere_path(id, NULL)))
|
||||
continue;
|
||||
if (mkdir_in_gitdir(rerere_path(id, NULL)) &&
|
||||
errno != EEXIST)
|
||||
continue; /* NEEDSWORK: perhaps we should die? */
|
||||
|
||||
/*
|
||||
* We are the first to encounter this
|
||||
* conflict. Ask handle_file() to write the
|
||||
* normalized contents to the "preimage" file.
|
||||
*/
|
||||
handle_file(path, NULL, rerere_path(id, "preimage"));
|
||||
id->collection->status |= RR_HAS_PREIMAGE;
|
||||
fprintf(stderr, "Recorded preimage for '%s'\n", path);
|
||||
if (id->collection->status & RR_HAS_PREIMAGE) {
|
||||
;
|
||||
} else {
|
||||
/*
|
||||
* We are the first to encounter this
|
||||
* conflict. Ask handle_file() to write the
|
||||
* normalized contents to the "preimage" file.
|
||||
*
|
||||
* NEEDSWORK: what should happen if we had a
|
||||
* leftover postimage that is totally
|
||||
* unrelated? Perhaps we should unlink it?
|
||||
*/
|
||||
handle_file(path, NULL, rerere_path(id, "preimage"));
|
||||
id->collection->status |= RR_HAS_PREIMAGE;
|
||||
fprintf(stderr, "Recorded preimage for '%s'\n", path);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < rr->nr; i++)
|
||||
|
@ -184,12 +184,27 @@ test_expect_success 'rerere updates postimage timestamp' '
|
||||
'
|
||||
|
||||
test_expect_success 'rerere clear' '
|
||||
rm $rr/postimage &&
|
||||
mv $rr/postimage .git/post-saved &&
|
||||
echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR &&
|
||||
git rerere clear &&
|
||||
! test -d $rr
|
||||
'
|
||||
|
||||
test_expect_success 'leftover directory' '
|
||||
git reset --hard &&
|
||||
mkdir -p $rr &&
|
||||
test_must_fail git merge first &&
|
||||
test -f $rr/preimage
|
||||
'
|
||||
|
||||
test_expect_success 'missing preimage' '
|
||||
git reset --hard &&
|
||||
mkdir -p $rr &&
|
||||
cp .git/post-saved $rr/postimage &&
|
||||
test_must_fail git merge first &&
|
||||
test -f $rr/preimage
|
||||
'
|
||||
|
||||
test_expect_success 'set up for garbage collection tests' '
|
||||
mkdir -p $rr &&
|
||||
echo Hello >$rr/preimage &&
|
||||
|
Loading…
Reference in New Issue
Block a user