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

"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
This commit is contained in:
Junio C Hamano 2016-02-05 14:54:10 -08:00
commit 90b99869d4
2 changed files with 24 additions and 5 deletions

View File

@ -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)
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;

View File

@ -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