I stole this from an email that arrived in my inbox immediately after subscribing:
####################################################
###                                              ###
### Note: This is a draft patch for review only, ###
###       please do not commit it.               ###
###                                              ###
####################################################
That said: the patch is fairly simple.
Sorry if the file isn't attached as text/plain or another friendly format, I 
don't know how to coerce a particular MIME type in Thunderbird.
Anyway, I was reading the sample scripts that svnadmin create put into my 
repository's "hooks" directory, and read this in the pre-revprop-change.tmpl file:
# The hook program can use the 'svnlook' utility to examine the
# existing value of the revision property.
Imagine my surprise when I actually attempted this, and discovered that svnlook 
can't actually view revision properties.
I looked at how 'svn proplist' and 'svn propget' work, and applied more-or-less 
the same logic changes to 'svnlook proplist' and 'svnlook propget'.  I did my 
best to mimic the surrounding coding style, and glanced over it once more after 
I read through HACKING.
I searched, but found no 'bite-sized' issue for this in the tracker.
--- log-message-worthy content follows ---
* svnlook/main.c
     (subcommand_plist, do_plist, subcommand_pget, do_pget): Modified to support
     listing/fetching revision properties in addition to normal versioned
     properties.
Index: subversion/svnlook/main.c
===================================================================
--- subversion/svnlook/main.c	(revision 12233)
+++ subversion/svnlook/main.c	(working copy)
@@ -72,7 +72,8 @@
   { 
     svnlook__version = SVN_OPT_FIRST_LONGOPT_ID,
     svnlook__show_ids,
-    svnlook__no_diff_deleted
+    svnlook__no_diff_deleted,
+    svnlook__revprop_opt
   };
 
 /*
@@ -107,6 +108,9 @@
     {"no-diff-deleted", svnlook__no_diff_deleted, 0,
      N_("do not print differences for deleted files")},
 
+    {"revprop",       svnlook__revprop_opt, 0,
+                      N_("operate on a revision property (use with -r)")},
+
     {0,               0, 0, 0}
   };
 
@@ -170,15 +174,17 @@
      {'r', 't'} },
 
     {"propget", subcommand_pget, {"pget", "pg"},
-     N_("usage: svnlook propget REPOS_PATH PROPNAME PATH_IN_REPOS\n\n"
-        "Print the raw value of a property on a path in the repository.\n"),
-     {'r', 't'} },
+     N_("usage: svnlook propget REPOS_PATH PROPNAME [PATH_IN_REPOS]\n\n"
+        "Print the raw value of a property on a path in the repository.\n"
+        "With --revprop, prints the raw value of a revision property.\n"),
+     {'r', 't', svnlook__revprop_opt} },
 
     {"proplist", subcommand_plist, {"plist", "pl"},
-     N_("usage: svnlook proplist REPOS_PATH PATH_IN_REPOS\n\n"
-        "List the properties of a path in the repository.\n"
+     N_("usage: svnlook proplist REPOS_PATH [PATH_IN_REPOS]\n\n"
+        "List the properties of a path in the repository, or\n"
+        "with the --revprop option, revision properties.\n"
         "With -v, show the property values too.\n"),
-     {'r', 't', 'v'} },
+     {'r', 't', 'v', svnlook__revprop_opt} },
 
     {"tree", subcommand_tree, {0},
      N_("usage: svnlook tree REPOS_PATH [PATH_IN_REPOS]\n\n"
@@ -213,6 +219,7 @@
   svn_boolean_t help;             /* --help */
   svn_boolean_t no_diff_deleted;  /* --no-diff-deleted */
   svn_boolean_t verbose;          /* --verbose */
+  svn_boolean_t revprop;          /* --revprop */
 };
 
 
@@ -1429,13 +1436,25 @@
   apr_size_t len;
   
   SVN_ERR (get_root (&root, c, pool));
-  SVN_ERR (verify_path (&kind, root, path, pool));
-  SVN_ERR (svn_fs_node_prop (&prop, root, path, propname, pool));
+  if (path != NULL)
+    {
+      SVN_ERR (verify_path (&kind, root, path, pool));
+      SVN_ERR (svn_fs_node_prop (&prop, root, path, propname, pool));
+    }
+  else
+      SVN_ERR (svn_fs_revision_prop (&prop, c->fs, c->rev_id, propname, pool));
 
   if (prop == NULL)
-    return svn_error_createf
-      (SVN_ERR_PROPERTY_NOT_FOUND, NULL,
-       _("Property '%s' not found on path '%s'"), propname, path);
+    {
+       if (path == NULL)
+         return svn_error_createf
+           (SVN_ERR_PROPERTY_NOT_FOUND, NULL,
+            _("Property '%s' not found on revision %d"), propname, c->rev_id);
+       else
+         return svn_error_createf
+           (SVN_ERR_PROPERTY_NOT_FOUND, NULL,
+            _("Property '%s' not found on path '%s'"), propname, path);
+    }
 
   /* Else. */
 
@@ -1468,10 +1487,15 @@
   apr_hash_index_t *hi;
   svn_node_kind_t kind;
 
+  SVN_ERR (svn_stream_for_stdout (&stdout_stream, pool));
   SVN_ERR (get_root (&root, c, pool));
-  SVN_ERR (verify_path (&kind, root, path, pool));
-  SVN_ERR (svn_fs_node_proplist (&props, root, path, pool));
-  SVN_ERR (svn_stream_for_stdout (&stdout_stream, pool));
+  if (path != NULL)
+    {
+      SVN_ERR (verify_path (&kind, root, path, pool));
+      SVN_ERR (svn_fs_node_proplist (&props, root, path, pool));
+    }
+  else
+      SVN_ERR (svn_fs_revision_proplist (&props, c->fs, c->rev_id, pool));
 
   for (hi = apr_hash_first (pool, props); hi; hi = apr_hash_next (hi))
     {
@@ -1724,7 +1748,7 @@
         (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
          _("Missing propname and repository path arguments"));
     }
-  else if (opt_state->arg2 == NULL)
+  else if (!opt_state->revprop && opt_state->arg2 == NULL)
     {
       return svn_error_createf
         (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
@@ -1732,7 +1756,7 @@
     }
 
   SVN_ERR (get_ctxt_baton (&c, opt_state, pool));
-  SVN_ERR (do_pget (c, opt_state->arg1, opt_state->arg2, pool));
+  SVN_ERR (do_pget (c, opt_state->arg1, opt_state->revprop ? NULL : opt_state->arg2, pool));
   return SVN_NO_ERROR;
 }
 
@@ -1742,14 +1766,23 @@
 {
   struct svnlook_opt_state *opt_state = baton;
   svnlook_ctxt_t *c;
+  
+  /* some might argue that we should error here if --revprop is specified
+   * with no explicit revision, instead of implicitly behaving as -r HEAD.
+   *
+   * Those people might be right, but I'll leave that change to them,
+   * primarily because I don't fully understand how error handling works
+   * in this code.
+   */
 
-  if (opt_state->arg1 == NULL)
+  if (!opt_state->revprop && opt_state->arg1 == NULL)
     return svn_error_createf
       (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
        _("Missing repository path argument"));
 
   SVN_ERR (get_ctxt_baton (&c, opt_state, pool));
-  SVN_ERR (do_plist (c, opt_state->arg1, opt_state->verbose, pool));
+  SVN_ERR (do_plist (c, opt_state->revprop ? NULL : opt_state->arg1, 
+                     opt_state->verbose, pool));
   return SVN_NO_ERROR;
 }
 
@@ -1896,6 +1929,10 @@
         case '?':
           opt_state.help = TRUE;
           break;
+          
+        case svnlook__revprop_opt:
+          opt_state.revprop = TRUE;
+          break;
 
         case svnlook__version:
           opt_state.version = TRUE;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Dec  8 03:01:26 2004