Browse Source

Merge branch 'dk/reflog-walk-with-non-commit'

"git reflog" incorrectly assumed that all objects that used to be
at the tip of a ref must be commits, which caused it to segfault.

* dk/reflog-walk-with-non-commit:
  reflog-walk: don't segfault on non-commit sha1's in the reflog
maint
Junio C Hamano 9 years ago
parent
commit
ceef512e79
  1. 16
      reflog-walk.c
  2. 13
      t/t1410-reflog.sh

16
reflog-walk.c

@ -221,6 +221,7 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) @@ -221,6 +221,7 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
struct commit_info *commit_info =
get_commit_info(commit, &info->reflogs, 0);
struct commit_reflog *commit_reflog;
struct object *logobj;
struct reflog_info *reflog;

info->last_commit_reflog = NULL;
@ -232,15 +233,20 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit) @@ -232,15 +233,20 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
commit->parents = NULL;
return;
}

reflog = &commit_reflog->reflogs->items[commit_reflog->recno];
info->last_commit_reflog = commit_reflog;
commit_reflog->recno--;
commit_info->commit = (struct commit *)parse_object(reflog->osha1);
if (!commit_info->commit) {

do {
reflog = &commit_reflog->reflogs->items[commit_reflog->recno];
commit_reflog->recno--;
logobj = parse_object(reflog->osha1);
} while (commit_reflog->recno && (logobj && logobj->type != OBJ_COMMIT));

if (!logobj || logobj->type != OBJ_COMMIT) {
commit_info->commit = NULL;
commit->parents = NULL;
return;
}
commit_info->commit = (struct commit *)logobj;

commit->parents = xcalloc(1, sizeof(struct commit_list));
commit->parents->item = commit_info->commit;

13
t/t1410-reflog.sh

@ -325,4 +325,17 @@ test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' ' @@ -325,4 +325,17 @@ test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' '
test_cmp expect actual
'

test_expect_success 'no segfaults for reflog containing non-commit sha1s' '
git update-ref --create-reflog -m "Creating ref" \
refs/tests/tree-in-reflog HEAD &&
git update-ref -m "Forcing tree" refs/tests/tree-in-reflog HEAD^{tree} &&
git update-ref -m "Restoring to commit" refs/tests/tree-in-reflog HEAD &&
git reflog refs/tests/tree-in-reflog
'

test_expect_failure 'reflog with non-commit entries displays all entries' '
git reflog refs/tests/tree-in-reflog >actual &&
test_line_count = 3 actual
'

test_done

Loading…
Cancel
Save