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

[PATCH] Issue 1241: svnlook not printing property diffs

From: John Szakmeister <john_at_szakmeister.net>
Date: 2003-05-10 17:54:05 CEST

Well, here is my first stab _ever_ at a patch... don't hurt me too bad. :-) This should
fix the problem of svnlook not printing property diffs. I basically copied several
functions from libsvn_client/diff.c and inserted them into main.c. Then I modified
print_diff_tree to grab and print the property differences.

-John

Fix issue #1241: svnlook not printing property diffs
* main.c
  (get_propchanges): New function.
  (diff_props_changed): New function
  (display_prop_diffs): New function
  (print_diff_tree): Updated to print property differences.

Index: subversion/svnlook/main.c
===================================================================
--- subversion/svnlook/main.c (revision 5879)
+++ subversion/svnlook/main.c (working copy)
@@ -670,6 +670,176 @@
 }
 
 
+/* Helper function to generate property changes between
+ revisions of a file*/
+static svn_error_t *
+get_propchanges (apr_array_header_t **local_propchanges,
+ apr_hash_t *localprops,
+ apr_hash_t *baseprops,
+ apr_pool_t *pool)
+{
+ apr_hash_index_t *hi;
+ apr_array_header_t *ary = apr_array_make (pool, 1, sizeof(svn_prop_t));
+
+ /* Note: we will be storing the pointers to the keys (from the hashes)
+ into the local_propchanges array. It is acceptable for us to
+ reference the same memory as the base/localprops hash. */
+
+ /* Loop over baseprops and examine each key. This will allow us to
+ detect any `deletion' events or `set-modification' events. */
+ for (hi = apr_hash_first (pool, baseprops); hi; hi = apr_hash_next (hi))
+ {
+ const void *key;
+ apr_ssize_t klen;
+ void *val;
+ const svn_string_t *propval1, *propval2;
+
+ /* Get next property */
+ apr_hash_this (hi, &key, &klen, &val);
+ propval1 = val;
+
+ /* Does property name exist in localprops? */
+ propval2 = apr_hash_get (localprops, key, klen);
+
+ if (propval2 == NULL)
+ {
+ /* Add a delete event to the array */
+ svn_prop_t *p = apr_array_push (ary);
+ p->name = key;
+ p->value = NULL;
+ }
+ else if (! svn_string_compare (propval1, propval2))
+ {
+ /* Add a set (modification) event to the array */
+ svn_prop_t *p = apr_array_push (ary);
+ p->name = key;
+ p->value = svn_string_dup (propval2, pool);
+ }
+ }
+
+ /* Loop over localprops and examine each key. This allows us to
+ detect `set-creation' events */
+ for (hi = apr_hash_first (pool, localprops); hi; hi = apr_hash_next (hi))
+ {
+ const void *key;
+ apr_ssize_t klen;
+ void *val;
+ const svn_string_t *propval;
+
+ /* Get next property */
+ apr_hash_this (hi, &key, &klen, &val);
+ propval = val;
+
+ /* Does property name exist in baseprops? */
+ if (NULL == apr_hash_get (baseprops, key, klen))
+ {
+ /* Add a set (creation) event to the array */
+ svn_prop_t *p = apr_array_push (ary);
+ p->name = key;
+ p->value = svn_string_dup (propval, pool);
+ }
+ }
+
+
+ /* Done building our array of user events. */
+ *local_propchanges = ary;
+
+ return SVN_NO_ERROR;
+}
+
+/* Helper function to display differences in properties of a file */
+static svn_error_t *
+display_prop_diffs (const apr_array_header_t *propchanges,
+ apr_hash_t *original_props,
+ const char *path,
+ apr_file_t *file,
+ apr_pool_t *pool)
+{
+ int i;
+
+ SVN_ERR (svn_io_file_printf (file, "\nProperty changes on: %s\n", path));
+ apr_file_printf (file,
+ "___________________________________________________________________\n");
+
+ for (i = 0; i < propchanges->nelts; i++)
+ {
+ const svn_prop_t *propchange
+ = &APR_ARRAY_IDX(propchanges, i, svn_prop_t);
+
+ const svn_string_t *original_value;
+
+ if (original_props)
+ original_value = apr_hash_get (original_props,
+ propchange->name, APR_HASH_KEY_STRING);
+ else
+ original_value = NULL;
+
+ SVN_ERR (svn_io_file_printf (file, "Name: %s\n", propchange->name));
+
+ /* For now, we have a rather simple heuristic: if this is an
+ "svn:" property, then assume the value is UTF-8 and must
+ therefore be converted before printing. Otherwise, just
+ print whatever's there and hope for the best. */
+ {
+ svn_boolean_t val_to_utf8 = svn_prop_is_svn_prop (propchange->name);
+ const char *printable_val;
+
+ if (original_value != NULL)
+ {
+ if (val_to_utf8)
+ SVN_ERR (svn_utf_cstring_from_utf8
+ (&printable_val, original_value->data, pool));
+ else
+ printable_val = original_value->data;
+
+ apr_file_printf (file, " - %s\n", printable_val);
+ }
+
+ if (propchange->value != NULL)
+ {
+ if (val_to_utf8)
+ SVN_ERR (svn_utf_cstring_from_utf8
+ (&printable_val, propchange->value->data, pool));
+ else
+ printable_val = propchange->value->data;
+
+ apr_file_printf (file, " + %s\n", printable_val);
+ }
+ }
+ }
+
+ apr_file_printf (file, "\n");
+
+ return SVN_NO_ERROR;
+}
+
+/* Helper function that will break out property changes that
+ are visible to the user */
+static svn_error_t *
+diff_props_changed (const apr_array_header_t *propchanges,
+ apr_hash_t *original_props,
+ const char *path,
+ apr_file_t *file,
+ apr_pool_t *pool)
+{
+ apr_array_header_t *entry_props, *wc_props, *regular_props;
+ apr_pool_t *subpool = svn_pool_create (pool);
+
+ SVN_ERR (svn_categorize_props (propchanges,
+ &entry_props, &wc_props, &regular_props,
+ subpool));
+
+ if (regular_props->nelts > 0)
+ SVN_ERR (display_prop_diffs (regular_props,
+ original_props,
+ path,
+ file,
+ subpool));
+
+ svn_pool_destroy (subpool);
+ return SVN_NO_ERROR;
+}
+
 /* Recursively print all nodes in the tree that have been modified
    (do not include directories affected only by "bubble-up"). */
 static svn_error_t *
@@ -825,6 +995,34 @@
       printf ("\n");
     }
     
+ if ((node->prop_mod) && (node->action != 'D'))
+ {
+ apr_file_t *outhandle;
+ apr_status_t apr_err;
+ apr_hash_t *local_proptable;
+ apr_hash_t *base_proptable;
+ apr_array_header_t *propchanges;
+
+ /* Get an apr_file_t representing stdout, which is where
+ we'll have the diff program print to. */
+ apr_err = apr_file_open_stdout (&outhandle, pool);
+ if (apr_err)
+ return svn_error_create
+ (apr_err, NULL,
+ "print_diff_tree: can't open handle to stdout");
+
+ SVN_ERR (svn_fs_node_proplist(&local_proptable, root, path, pool));
+
+ if(node->action != 'A')
+ SVN_ERR (svn_fs_node_proplist(&base_proptable, base_root, base_path, pool));
+ else
+ base_proptable = apr_hash_make(pool);
+
+ SVN_ERR (get_propchanges(&propchanges, local_proptable, base_proptable, pool));
+
+ diff_props_changed(propchanges, base_proptable, path, outhandle, pool);
+ }
+
   /* Now, delete any temporary files. */
   if (orig_path)
     svn_io_remove_file (orig_path, pool);

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat May 10 17:55:35 2003

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.