aboutsummaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2014-12-22 12:27:32 -0800
committerJunio C Hamano <gitster@pobox.com>2014-12-22 12:27:32 -0800
commit6f3abb7a8743bbd0bffa11a3f5df84d0da532c59 (patch)
tree05d573b673ca97526d8a1a1c05dc4b3672ed89ec /refs.c
parent12b9f08953f4f558789f833b0fe438c25ce6d4b1 (diff)
parent69216bf72be2be4f8aa932324b3145d3f395cdc6 (diff)
downloadgit-6f3abb7a8743bbd0bffa11a3f5df84d0da532c59.tar.gz
git-6f3abb7a8743bbd0bffa11a3f5df84d0da532c59.tar.xz
Merge branch 'jk/for-each-reflog-ent-reverse'
The code that reads the reflog from the newer to the older entries did not handle an entry that crosses a boundary of block it uses to read them correctly. * jk/for-each-reflog-ent-reverse: for_each_reflog_ent_reverse: turn leftover check into assertion for_each_reflog_ent_reverse: fix newlines on block boundaries
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/refs.c b/refs.c
index 898d3c2ca..bfe4ba421 100644
--- a/refs.c
+++ b/refs.c
@@ -3413,29 +3413,54 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void
bp = find_beginning_of_line(buf, scanp);
- if (*bp != '\n') {
- strbuf_splice(&sb, 0, 0, buf, endp - buf);
- if (pos)
- break; /* need to fill another block */
- scanp = buf - 1; /* leave loop */
- } else {
+ if (*bp == '\n') {
/*
- * (bp + 1) thru endp is the beginning of the
- * current line we have in sb
+ * The newline is the end of the previous line,
+ * so we know we have complete line starting
+ * at (bp + 1). Prefix it onto any prior data
+ * we collected for the line and process it.
*/
strbuf_splice(&sb, 0, 0, bp + 1, endp - (bp + 1));
scanp = bp;
endp = bp + 1;
+ ret = show_one_reflog_ent(&sb, fn, cb_data);
+ strbuf_reset(&sb);
+ if (ret)
+ break;
+ } else if (!pos) {
+ /*
+ * We are at the start of the buffer, and the
+ * start of the file; there is no previous
+ * line, and we have everything for this one.
+ * Process it, and we can end the loop.
+ */
+ strbuf_splice(&sb, 0, 0, buf, endp - buf);
+ ret = show_one_reflog_ent(&sb, fn, cb_data);
+ strbuf_reset(&sb);
+ break;
}
- ret = show_one_reflog_ent(&sb, fn, cb_data);
- strbuf_reset(&sb);
- if (ret)
+
+ if (bp == buf) {
+ /*
+ * We are at the start of the buffer, and there
+ * is more file to read backwards. Which means
+ * we are in the middle of a line. Note that we
+ * may get here even if *bp was a newline; that
+ * just means we are at the exact end of the
+ * previous line, rather than some spot in the
+ * middle.
+ *
+ * Save away what we have to be combined with
+ * the data from the next read.
+ */
+ strbuf_splice(&sb, 0, 0, buf, endp - buf);
break;
+ }
}
}
if (!ret && sb.len)
- ret = show_one_reflog_ent(&sb, fn, cb_data);
+ die("BUG: reverse reflog parser had leftover data");
fclose(logfp);
strbuf_release(&sb);