* [PATCH] vcs-svn: fix broken test 'keep content, but change mode'
@ 2011-08-25 16:02 Dmitry Ivankov
2011-08-25 16:08 ` Dmitry Ivankov
0 siblings, 1 reply; 2+ messages in thread
From: Dmitry Ivankov @ 2011-08-25 16:02 UTC (permalink / raw)
To: git; +Cc: Jonathan Nieder, David Barr, Ramkumar Ramachandra, Dmitry Ivankov
svn symlinks are files with "link destination" content and a
"svn:special=*" property set. These are imported as blobs with
"destination" content and S_IFLNK mode. When svn copy a file without
altering it's content(but maybe altering it's mode), we reuse the blob
object thus loosing or not adding the "link " prefix.
But we take possible prefix into account when applying svn deltas. And
this is the only place we ask fast-import for original blob. So pretend
that we want to apply a zero delta to resolve the issue.
There is some overhead due to using a temporary file to store such a small
blob. But hopefully such node change is too rare to care.
Signed-off-by: Dmitry Ivankov <divanorama@gmail.com>
---
This could be done better if we just read the cat-blob to memory, added or
removed the "link " prefix and wrote it to the stream, because the link
destination should be a tiny string. But on the other hand it'd blow up
if for some reason it's huge.
And taking into account that changing file mode from/to link without a
content change should be extremely rare anyway, I think it's ok.
Maybe it is redundant to add svndiff0_identity function to just cat blob
to a temporary file. The excuse is that svndiff.c is the only user of this
temporary file and the cat-blob response, so keep it there.
The patch base is svn-fe branch at git://repo.or.cz/git/jrn.git
Not backporting it to git master because vcs-svn stuff differs quite much
around this change.
t/t9010-svn-fe.sh | 2 +-
vcs-svn/fast_export.c | 6 +++++-
vcs-svn/svndiff.c | 17 +++++++++++++++++
vcs-svn/svndiff.h | 1 +
vcs-svn/svndump.c | 16 +++++++++++++++-
5 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index b7eed24..b6bdfeb 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -413,7 +413,7 @@ test_expect_success PIPE 'action: add node without text' '
try_dump textless.dump must_fail
'
-test_expect_failure PIPE 'change file mode but keep old content' '
+test_expect_success PIPE 'change file mode but keep old content' '
reinit_git &&
cat >expect <<-\EOF &&
OBJID
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
index 19d7c34..8c7295f 100644
--- a/vcs-svn/fast_export.c
+++ b/vcs-svn/fast_export.c
@@ -209,7 +209,11 @@ static long apply_delta(off_t len, struct line_buffer *input,
preimage.max_off += strlen("link ");
check_preimage_overflow(preimage.max_off, 1);
}
- if (svndiff0_apply(input, len, &preimage, out))
+
+ if (!input) {
+ if (svndiff0_identity(&preimage, out))
+ die("cannot cat blob");
+ } else if (svndiff0_apply(input, len, &preimage, out))
die("cannot apply delta");
if (old_data) {
/* Read the remainder of preimage and trailing newline. */
diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c
index 9ee41bb..bf104db 100644
--- a/vcs-svn/svndiff.c
+++ b/vcs-svn/svndiff.c
@@ -306,3 +306,20 @@ int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
}
return 0;
}
+int svndiff0_identity(struct sliding_view *preimage, FILE *postimage)
+{
+ assert(preimage && postimage);
+ off_t pre_off = 0;
+
+ while (pre_off != preimage->max_off) {
+ size_t pre_len = 8192;
+ if (pre_off + pre_len > preimage->max_off)
+ pre_len = preimage->max_off - pre_off;
+ if (move_window(preimage, pre_off, pre_len) ||
+ write_strbuf(&preimage->buf, postimage))
+ return -1;
+ pre_off += pre_len;
+ }
+
+ return 0;
+}
diff --git a/vcs-svn/svndiff.h b/vcs-svn/svndiff.h
index 74eb464..5afa3f2 100644
--- a/vcs-svn/svndiff.h
+++ b/vcs-svn/svndiff.h
@@ -6,5 +6,6 @@ struct sliding_view;
extern int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
struct sliding_view *preimage, FILE *postimage);
+extern int svndiff0_identity(struct sliding_view *preimage, FILE *postimage);
#endif
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index b1f4161..1e7ed48 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -285,7 +285,21 @@ static void handle_node(void)
/* For the fast_export_* functions, NULL means empty. */
old_data = NULL;
if (!have_text) {
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data);
+ /*
+ * This is clean content copy in svn, but we alter the content
+ * of symlinks (add/remove "link " prefix used by svn). So when
+ * mode changes from/to symlink specify (recreate) data inline.
+ */
+ if (node_ctx.type != old_mode && (old_mode == REPO_MODE_LNK
+ || node_ctx.type == REPO_MODE_LNK)) {
+
+ fast_export_modify(node_ctx.dst.buf,
+ node_ctx.type, "inline");
+ fast_export_blob_delta(node_ctx.type, old_mode,
+ old_data, 0, NULL);
+ } else
+ fast_export_modify(node_ctx.dst.buf,
+ node_ctx.type, old_data);
return;
}
if (!node_ctx.text_delta) {
--
1.7.3.4
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] vcs-svn: fix broken test 'keep content, but change mode'
2011-08-25 16:02 [PATCH] vcs-svn: fix broken test 'keep content, but change mode' Dmitry Ivankov
@ 2011-08-25 16:08 ` Dmitry Ivankov
0 siblings, 0 replies; 2+ messages in thread
From: Dmitry Ivankov @ 2011-08-25 16:08 UTC (permalink / raw)
To: git; +Cc: Jonathan Nieder, Ramkumar Ramachandra, Dmitry Ivankov, David Barr
correct David's email (on first attempt I've accidentally used the old
one, taken from some git history)
On Thu, Aug 25, 2011 at 10:02 PM, Dmitry Ivankov <divanorama@gmail.com> wrote:
> svn symlinks are files with "link destination" content and a
> "svn:special=*" property set. These are imported as blobs with
> "destination" content and S_IFLNK mode. When svn copy a file without
> altering it's content(but maybe altering it's mode), we reuse the blob
> object thus loosing or not adding the "link " prefix.
>
> But we take possible prefix into account when applying svn deltas. And
> this is the only place we ask fast-import for original blob. So pretend
> that we want to apply a zero delta to resolve the issue.
>
> There is some overhead due to using a temporary file to store such a small
> blob. But hopefully such node change is too rare to care.
>
> Signed-off-by: Dmitry Ivankov <divanorama@gmail.com>
> ---
> This could be done better if we just read the cat-blob to memory, added or
> removed the "link " prefix and wrote it to the stream, because the link
> destination should be a tiny string. But on the other hand it'd blow up
> if for some reason it's huge.
>
> And taking into account that changing file mode from/to link without a
> content change should be extremely rare anyway, I think it's ok.
>
> Maybe it is redundant to add svndiff0_identity function to just cat blob
> to a temporary file. The excuse is that svndiff.c is the only user of this
> temporary file and the cat-blob response, so keep it there.
>
> The patch base is svn-fe branch at git://repo.or.cz/git/jrn.git
> Not backporting it to git master because vcs-svn stuff differs quite much
> around this change.
>
> t/t9010-svn-fe.sh | 2 +-
> vcs-svn/fast_export.c | 6 +++++-
> vcs-svn/svndiff.c | 17 +++++++++++++++++
> vcs-svn/svndiff.h | 1 +
> vcs-svn/svndump.c | 16 +++++++++++++++-
> 5 files changed, 39 insertions(+), 3 deletions(-)
>
> diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
> index b7eed24..b6bdfeb 100755
> --- a/t/t9010-svn-fe.sh
> +++ b/t/t9010-svn-fe.sh
> @@ -413,7 +413,7 @@ test_expect_success PIPE 'action: add node without text' '
> try_dump textless.dump must_fail
> '
>
> -test_expect_failure PIPE 'change file mode but keep old content' '
> +test_expect_success PIPE 'change file mode but keep old content' '
> reinit_git &&
> cat >expect <<-\EOF &&
> OBJID
> diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c
> index 19d7c34..8c7295f 100644
> --- a/vcs-svn/fast_export.c
> +++ b/vcs-svn/fast_export.c
> @@ -209,7 +209,11 @@ static long apply_delta(off_t len, struct line_buffer *input,
> preimage.max_off += strlen("link ");
> check_preimage_overflow(preimage.max_off, 1);
> }
> - if (svndiff0_apply(input, len, &preimage, out))
> +
> + if (!input) {
> + if (svndiff0_identity(&preimage, out))
> + die("cannot cat blob");
> + } else if (svndiff0_apply(input, len, &preimage, out))
> die("cannot apply delta");
> if (old_data) {
> /* Read the remainder of preimage and trailing newline. */
> diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c
> index 9ee41bb..bf104db 100644
> --- a/vcs-svn/svndiff.c
> +++ b/vcs-svn/svndiff.c
> @@ -306,3 +306,20 @@ int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
> }
> return 0;
> }
> +int svndiff0_identity(struct sliding_view *preimage, FILE *postimage)
> +{
> + assert(preimage && postimage);
> + off_t pre_off = 0;
> +
> + while (pre_off != preimage->max_off) {
> + size_t pre_len = 8192;
> + if (pre_off + pre_len > preimage->max_off)
> + pre_len = preimage->max_off - pre_off;
> + if (move_window(preimage, pre_off, pre_len) ||
> + write_strbuf(&preimage->buf, postimage))
> + return -1;
> + pre_off += pre_len;
> + }
> +
> + return 0;
> +}
> diff --git a/vcs-svn/svndiff.h b/vcs-svn/svndiff.h
> index 74eb464..5afa3f2 100644
> --- a/vcs-svn/svndiff.h
> +++ b/vcs-svn/svndiff.h
> @@ -6,5 +6,6 @@ struct sliding_view;
>
> extern int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
> struct sliding_view *preimage, FILE *postimage);
> +extern int svndiff0_identity(struct sliding_view *preimage, FILE *postimage);
>
> #endif
> diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
> index b1f4161..1e7ed48 100644
> --- a/vcs-svn/svndump.c
> +++ b/vcs-svn/svndump.c
> @@ -285,7 +285,21 @@ static void handle_node(void)
> /* For the fast_export_* functions, NULL means empty. */
> old_data = NULL;
> if (!have_text) {
> - fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data);
> + /*
> + * This is clean content copy in svn, but we alter the content
> + * of symlinks (add/remove "link " prefix used by svn). So when
> + * mode changes from/to symlink specify (recreate) data inline.
> + */
> + if (node_ctx.type != old_mode && (old_mode == REPO_MODE_LNK
> + || node_ctx.type == REPO_MODE_LNK)) {
> +
> + fast_export_modify(node_ctx.dst.buf,
> + node_ctx.type, "inline");
> + fast_export_blob_delta(node_ctx.type, old_mode,
> + old_data, 0, NULL);
> + } else
> + fast_export_modify(node_ctx.dst.buf,
> + node_ctx.type, old_data);
> return;
> }
> if (!node_ctx.text_delta) {
> --
> 1.7.3.4
>
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-08-25 16:08 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-25 16:02 [PATCH] vcs-svn: fix broken test 'keep content, but change mode' Dmitry Ivankov
2011-08-25 16:08 ` Dmitry Ivankov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox