Skip to content

Commit

Permalink
Merge branch 'dk/reflog-walk-with-non-commit'
Browse files Browse the repository at this point in the history
"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
  • Loading branch information
Junio C Hamano committed Jan 20, 2016
2 parents 1576f78 + aecad37 commit ceef512
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
16 changes: 11 additions & 5 deletions reflog-walk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions t/t1410-reflog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit ceef512

Please sign in to comment.