[PATCH 10/8] vcs-svn: Consume whole preimage when applying deltas

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Date: Sun Nov 21 20:24:12 2010 -0600

Some deltas do not consume the entire preimage, so we have to
consume it explicitly.

Noticed during imports from the ASF repo.

Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx>
---
Jonathan Nieder wrote:

> +++ b/vcs-svn/fast_export.c
> @@ -102,33 +115,39 @@ static const char *get_response_line(void)
[...]
> +	if (svndiff0_apply(input, len, &preimage, out))
> +		die("cannot apply delta");
> +	if (old_mark) {
> +		/* Discard trailing newline from cat-blob-fd. */
> +		const char *tail = get_response_line();
> +		if (!tail || *tail)
> +			die("missing newline after cat-blob response");

As mentioned before, this error

	fatal: missing newline after cat-blob response

and

	error: Preimage ends early

were sometimes triggering.  Here's a fix for squashing.  Sorry for
the nonsensical code.

 t/t9010-svn-fe.sh     |  108 +++++++++++++++++++++++++++++++++++++++++++++++++
 vcs-svn/fast_export.c |   16 ++++---
 2 files changed, 117 insertions(+), 7 deletions(-)

diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index 6c8b803..1776a38 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -678,6 +678,114 @@ test_expect_success 'deltas for typechange' '
 	test_cmp expect actual
 '
 
+test_expect_success PIPE 'deltas need not consume the whole preimage' '
+	reinit_git &&
+	cat >expect <<-\EOF &&
+	OBJID
+	:120000 100644 OBJID OBJID T	postimage
+	OBJID
+	:100644 120000 OBJID OBJID T	postimage
+	OBJID
+	:000000 100644 OBJID OBJID A	postimage
+	EOF
+	echo "first preimage" >expect.1 &&
+	printf target >expect.2 &&
+	printf lnk >expect.3 &&
+	rm -f backflow &&
+	{
+		printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" |
+		q_to_nul
+	} >delta.1 &&
+	{
+		properties svn:special "*" &&
+		echo PROPS-END
+	} >symlink.props &&
+	{
+		printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" |
+		q_to_nul
+	} >delta.2 &&
+	{
+		printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" |
+		q_to_nul
+	} >delta.3 &&
+	{
+		cat <<-\EOF &&
+		SVN-fs-dump-format-version: 3
+
+		Revision-number: 1
+		Prop-content-length: 10
+		Content-length: 10
+
+		PROPS-END
+
+		Node-path: postimage
+		Node-kind: file
+		Node-action: add
+		Text-delta: true
+		Prop-content-length: 10
+		EOF
+		echo Text-content-length: $(wc -c <delta.1) &&
+		echo Content-length: $((10 + $(wc -c <delta.1))) &&
+		echo &&
+		echo PROPS-END &&
+		cat delta.1 &&
+		cat <<-\EOF &&
+
+		Revision-number: 2
+		Prop-content-length: 10
+		Content-length: 10
+
+		PROPS-END
+
+		Node-path: postimage
+		Node-kind: file
+		Node-action: change
+		Text-delta: true
+		EOF
+		echo Prop-content-length: $(wc -c <symlink.props) &&
+		echo Text-content-length: $(wc -c <delta.2) &&
+		echo Content-length: $(($(wc -c <symlink.props) + $(wc -c <delta.2))) &&
+		echo &&
+		cat symlink.props &&
+		cat delta.2 &&
+		cat <<-\EOF &&
+
+		Revision-number: 3
+		Prop-content-length: 10
+		Content-length: 10
+
+		PROPS-END
+
+		Node-path: postimage
+		Node-kind: file
+		Node-action: change
+		Text-delta: true
+		Prop-content-length: 10
+		EOF
+		echo Text-content-length: $(wc -c <delta.3) &&
+		echo Content-length: $((10 + $(wc -c <delta.3))) &&
+		echo &&
+		echo PROPS-END &&
+		cat delta.3 &&
+		echo
+	} >deltapartial.dump &&
+	mkfifo backflow &&
+	test-svn-fe deltapartial.dump 3<backflow |
+	git fast-import --cat-blob-fd=3 3>backflow &&
+	{
+		git rev-list HEAD |
+		git diff-tree --root --stdin |
+		sed "s/$_x40/OBJID/g"
+	} >actual &&
+	test_cmp expect actual &&
+	git show HEAD:postimage >actual.3 &&
+	git show HEAD^:postimage >actual.2 &&
+	git show HEAD^^:postimage >actual.1 &&
+	test_cmp expect.1 actual.1 &&
+	test_cmp expect.2 actual.2 &&
+	test_cmp expect.3 actual.3
+'
+
 test_expect_success 't9135/svn.dump' '
 	svnadmin create simple-svn &&
 	svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index ceb1fc5..f8a41e7 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -119,6 +119,7 @@ static long apply_delta(uint32_t mark, off_t len, struct line_buffer *input,
 			uint32_t old_mark, uint32_t old_mode)
 {
 	long ret;
+	off_t preimage_len = 0;
 	struct view preimage = {REPORT_FILENO, 0, STRBUF_INIT};
 	FILE *out;
 
@@ -126,22 +127,23 @@ static long apply_delta(uint32_t mark, off_t len, struct line_buffer *input,
 		die("cannot open temporary file for blob retrieval");
 	if (old_mark) {
 		const char *response;
-		off_t dummy;
 		printf("cat-blob :%"PRIu32"\n", old_mark);
 		fflush(stdout);
 		response = get_response_line();
-		/* Not necessary, just for robustness */
-		if (parse_cat_response_line(response, &dummy))
+		if (parse_cat_response_line(response, &preimage_len))
 			die("invalid cat-blob response: %s", response);
 	}
-	if (old_mode == REPO_MODE_LNK)
+	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_mark) {
-		/* Discard trailing newline from cat-blob-fd. */
-		const char *tail = get_response_line();
-		if (!tail || *tail)
+		/* 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);
-- 
1.7.2.4

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]