Browse Source

checkout.c: use ref_exists instead of file_exist

Change checkout.c to check if a ref exists instead of checking if a loose ref
file exists when deciding if to delete an orphaned log file. Otherwise, if a
ref only exists as a packed ref without a corresponding loose ref for the
currently checked out branch, we risk that the reflog will be deleted when we
switch to a different branch.

Update the reflog tests to check for this bug.

The following reproduces the bug:
$ git init-db
$ git config core.logallrefupdates true
$ git commit -m Initial --allow-empty
    [master (root-commit) bb11abe] Initial
$ git reflog master
    [8561dcb master@{0}: commit (initial): Initial]
$ find .git/{refs,logs} -type f | grep master
    [.git/refs/heads/master]
    [.git/logs/refs/heads/master]
$ git branch foo
$ git pack-refs --all
$ find .git/{refs,logs} -type f | grep master
    [.git/logs/refs/heads/master]
$ git checkout foo
$ find .git/{refs,logs} -type f | grep master
    ... reflog file is missing ...
$ git reflog master
    ... nothing ...

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
Acked-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Ronnie Sahlberg 11 years ago committed by Junio C Hamano
parent
commit
482b8f3208
  1. 5
      builtin/checkout.c
  2. 8
      t/t1410-reflog.sh

5
builtin/checkout.c

@ -651,10 +651,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
} }
} }
if (old->path && old->name) { if (old->path && old->name) {
char ref_file[PATH_MAX]; if (!ref_exists(old->path) && reflog_exists(old->path))

git_snpath(ref_file, sizeof(ref_file), "%s", old->path);
if (!file_exists(ref_file) && reflog_exists(old->path))
delete_reflog(old->path); delete_reflog(old->path);
} }
} }

8
t/t1410-reflog.sh

@ -245,4 +245,12 @@ test_expect_success 'gc.reflogexpire=false' '


' '


test_expect_success 'checkout should not delete log for packed ref' '
test $(git reflog master | wc -l) = 4 &&
git branch foo &&
git pack-refs --all &&
git checkout foo &&
test $(git reflog master | wc -l) = 4
'

test_done test_done

Loading…
Cancel
Save