Skip to content

Commit ceef512

Browse files
committed
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
2 parents 1576f78 + aecad37 commit ceef512

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

reflog-walk.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
221221
struct commit_info *commit_info =
222222
get_commit_info(commit, &info->reflogs, 0);
223223
struct commit_reflog *commit_reflog;
224+
struct object *logobj;
224225
struct reflog_info *reflog;
225226

226227
info->last_commit_reflog = NULL;
@@ -232,15 +233,20 @@ void fake_reflog_parent(struct reflog_walk_info *info, struct commit *commit)
232233
commit->parents = NULL;
233234
return;
234235
}
235-
236-
reflog = &commit_reflog->reflogs->items[commit_reflog->recno];
237236
info->last_commit_reflog = commit_reflog;
238-
commit_reflog->recno--;
239-
commit_info->commit = (struct commit *)parse_object(reflog->osha1);
240-
if (!commit_info->commit) {
237+
238+
do {
239+
reflog = &commit_reflog->reflogs->items[commit_reflog->recno];
240+
commit_reflog->recno--;
241+
logobj = parse_object(reflog->osha1);
242+
} while (commit_reflog->recno && (logobj && logobj->type != OBJ_COMMIT));
243+
244+
if (!logobj || logobj->type != OBJ_COMMIT) {
245+
commit_info->commit = NULL;
241246
commit->parents = NULL;
242247
return;
243248
}
249+
commit_info->commit = (struct commit *)logobj;
244250

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

t/t1410-reflog.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,4 +325,17 @@ test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' '
325325
test_cmp expect actual
326326
'
327327

328+
test_expect_success 'no segfaults for reflog containing non-commit sha1s' '
329+
git update-ref --create-reflog -m "Creating ref" \
330+
refs/tests/tree-in-reflog HEAD &&
331+
git update-ref -m "Forcing tree" refs/tests/tree-in-reflog HEAD^{tree} &&
332+
git update-ref -m "Restoring to commit" refs/tests/tree-in-reflog HEAD &&
333+
git reflog refs/tests/tree-in-reflog
334+
'
335+
336+
test_expect_failure 'reflog with non-commit entries displays all entries' '
337+
git reflog refs/tests/tree-in-reflog >actual &&
338+
test_line_count = 3 actual
339+
'
340+
328341
test_done

0 commit comments

Comments
 (0)