aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-01-20 11:43:32 -0800
committerJunio C Hamano <gitster@pobox.com>2016-01-20 11:43:32 -0800
commitceef512e797115ae581cfbfd220334e20f1c7b28 (patch)
treebcb722598337cc1b9845172954de89432950dab8
parent1576f783425b9cb7f7e54839c4a66adb2e95afea (diff)
parentaecad374ae7492cc7b2add5fa416d43e1f68c18e (diff)
downloadgit-ceef512e797115ae581cfbfd220334e20f1c7b28.tar.gz
git-ceef512e797115ae581cfbfd220334e20f1c7b28.tar.xz
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
-rw-r--r--reflog-walk.c16
-rwxr-xr-xt/t1410-reflog.sh13
2 files changed, 24 insertions, 5 deletions
diff --git a/reflog-walk.c b/reflog-walk.c
index 85b8a5424..0ebd1da5c 100644
--- a/reflog-walk.c
+++ b/reflog-walk.c
@@ -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;
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index b79049f6f..17a194bfa 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -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