[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: 'svn blame' speedup in 1.2

From: Philip Martin <philip_at_codematters.co.uk>
Date: 2005-03-26 23:42:51 CET

Daniel Berlin <dberlin@dberlin.org> writes:

> Theoretically, one should be able to use the libsvn_diff API, which
> tells you "lines from start to end in original were modified to become
> lines start to end in new file", and produce the explicit adds and
> deletes from that, but i haven't been able to get it to work right.
>
> In fact, diff -n is more or less doing this in order to produce the info
> it gives us. So we should be able to do it too :).

I'm not quite sure what you need, or what you can't get to work.

The patch below is a quick hack that overides the current diff output
vtable, so it's not suitable for the repository. Diff clients, like
the test program 'subversion/tests/libsvn_diff/diff-test', will output
approximate 'diff -n' output (the patch reuses the unified code so
each line representing an added line has a leading space).

Subversion and GNU sometimes choose different sequences to convert one
file into another so their outputs don't always match but they should
effect the same transformation.

Index: subversion/libsvn_diff/diff_file.c
===================================================================
--- subversion/libsvn_diff/diff_file.c (revision 13689)
+++ subversion/libsvn_diff/diff_file.c (working copy)
@@ -805,6 +805,45 @@
 }
 
 static
+svn_error_t *
+file_output_rcs_diff_modified(void *baton,
+ apr_off_t original_start,
+ apr_off_t original_length,
+ apr_off_t modified_start,
+ apr_off_t modified_length,
+ apr_off_t latest_start,
+ apr_off_t latest_length)
+{
+ svn_diff__file_output_baton_t *output_baton = baton;
+
+ if (original_length > 0)
+ printf("d%ld %ld\n", original_start + 1, original_length);
+
+ if (modified_length > 0)
+ {
+ printf("a%ld %ld\n", original_start + original_length, modified_length);
+
+ while (output_baton->current_line[1] < modified_start)
+ SVN_ERR(svn_diff__file_output_unified_line
+ (output_baton, svn_diff__file_output_unified_skip, 1));
+ while (output_baton->current_line[1] < modified_start + modified_length)
+ SVN_ERR(svn_diff__file_output_unified_line
+ (output_baton, svn_diff__file_output_unified_context, 1));
+
+ {
+ apr_size_t hunk_len = output_baton->hunk->len;
+ SVN_ERR(svn_stream_write(output_baton->output_stream,
+ output_baton->hunk->data,
+ &hunk_len));
+ output_baton->hunk_length[1] = 0;
+ svn_stringbuf_setempty(output_baton->hunk);
+ }
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static
 const char *
 svn_diff__file_output_unified_default_hdr(apr_pool_t *pool,
                                           const char *path)
@@ -826,7 +865,7 @@
 static const svn_diff_output_fns_t svn_diff__file_output_unified_vtable =
 {
   NULL, /* output_common */
- svn_diff__file_output_unified_diff_modified,
+ file_output_rcs_diff_modified,
   NULL, /* output_diff_latest */
   NULL, /* output_diff_common */
   NULL /* output_conflict */

-- 
Philip Martin
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Mar 26 23:47:31 2005

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.