From: Jonathan Nieder Date: Wed, 15 Jun 2011 07:31:35 +0000 (-0500) Subject: Merge branch 'db/delta-applier' into db/text-delta X-Git-Tag: v1.7.10-rc0~118^2~4^2~2^2~2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=157415a9a9589a1e8af28e68c6664d39c34877af;p=git.git Merge branch 'db/delta-applier' into db/text-delta * db/delta-applier: vcs-svn: cap number of bytes read from sliding view test-svn-fe: split off "test-svn-fe -d" into a separate function --- 157415a9a9589a1e8af28e68c6664d39c34877af diff --cc vcs-svn/fast_export.c index 005674d8c,99ed70b88..edc658d4f --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@@ -155,74 -73,7 +155,74 @@@ static void die_short_read(struct line_ die("invalid dump: unexpected end of file"); } -void fast_export_blob(uint32_t mode, uint32_t mark, uint32_t len, struct line_buffer *input) +static int ends_with(const char *s, size_t len, const char *suffix) +{ + const size_t suffixlen = strlen(suffix); + if (len < suffixlen) + return 0; + return !memcmp(s + len - suffixlen, suffix, suffixlen); +} + +static int parse_cat_response_line(const char *header, off_t *len) +{ + size_t headerlen = strlen(header); + const char *type; + const char *end; + + if (ends_with(header, headerlen, " missing")) + return error("cat-blob reports missing blob: %s", header); + type = memmem(header, headerlen, " blob ", strlen(" blob ")); + if (!type) + return error("cat-blob header has wrong object type: %s", header); + *len = strtoumax(type + strlen(" blob "), (char **) &end, 10); + if (end == type + strlen(" blob ")) + return error("cat-blob header does not contain length: %s", header); + if (*end) + return error("cat-blob header contains garbage after length: %s", header); + return 0; +} + +static long apply_delta(off_t len, struct line_buffer *input, + const char *old_data, uint32_t old_mode) +{ + long ret; + off_t preimage_len = 0; - struct sliding_view preimage = SLIDING_VIEW_INIT(&report_buffer); ++ struct sliding_view preimage = SLIDING_VIEW_INIT(&report_buffer, -1); + FILE *out; + + if (init_postimage() || !(out = buffer_tmpfile_rewind(&postimage))) + die("cannot open temporary file for blob retrieval"); + if (init_report_buffer(REPORT_FILENO)) + die("cannot open fd 3 for feedback from fast-import"); + if (old_data) { + const char *response; + printf("cat-blob %s\n", old_data); + fflush(stdout); + response = get_response_line(); + if (parse_cat_response_line(response, &preimage_len)) + die("invalid cat-blob response: %s", response); + } + if (old_mode == REPO_MODE_LNK) { + strbuf_addstr(&preimage.buf, "link "); + preimage_len += strlen("link "); + } + if (svndiff0_apply(input, len, &preimage, out)) + die("cannot apply delta"); + if (old_data) { + /* Read the remainder of preimage and trailing newline. */ + if (move_window(&preimage, preimage_len, 1)) + die("cannot seek to end of input"); + if (preimage.buf.buf[0] != '\n') + die("missing newline after cat-blob response"); + } + ret = buffer_tmpfile_prepare_to_read(&postimage); + if (ret < 0) + die("cannot read temporary file for blob retrieval"); + strbuf_release(&preimage.buf); + return ret; +} + +void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input) { if (mode == REPO_MODE_LNK) { /* svn symlink blobs start with "link " */