subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r1624039 - in /subversion/branches/log-message-templates/subversion: include/svn_client.h libsvn_client/commit_util.c svn/util.c tests/libsvn_client/client-test.c
Date Wed, 10 Sep 2014 15:46:10 GMT
Author: stsp
Date: Wed Sep 10 15:46:10 2014
New Revision: 1624039

URL: http://svn.apache.org/r1624039
Log:
On the log-message-templates branch, rework the log message template API
to properly support copies and deletions.

The svn_client_get_log_message_templates() function is renamed to
svn_client_get_log_message_template() (no trailing 's') and now accepts
only a single path or URL, but with revision and peg revision information.
This makes it possible to request log templates for any path at any revision.

The svn_client_get_log_message_templates_for_commit_items() function's
interface is unchanged but internally wraps the changed API and now
supports copied commit items.

This fixes cases such as where a branch is re-surrected from a formerly
deleted branch which had an svn:log-template property set on it.
The commit which re-creates the branch now uses a log template that
was defined on the deleted branch, in addition to any templates defined
on the parent directories of the newly resurrected branch.

* subversion/include/svn_client.h
  (svn_client_get_log_message_templates): Rename to ...
  (svn_client_get_log_message_template): ... this, and change parameters
   as follows: The paths_or_urls input array is replaced with a single
   path_or_url parameter. The output paramter log_message_templates is
   replaced with three output parameters log_message_template,
   defining_repos_relpath, and actual_revnum.
   Add new input parameters peg_revision and revision.
  (svn_client_get_log_message_templates_for_commit_items): Adjust docstring.
   This function no longer returns a NULL hash if no templates were found,
   but an empty hash.

* subversion/libsvn_client/commit_util.c
  (svn_client_get_log_message_templates): Rename to ...
  (svn_client_get_log_message_template): ... this, and implement the
   changed API.
  (svn_client_get_log_message_templates_for_commit_items): Adjust caller.
   Properly support copied commit items.
  
* subversion/svn/util.c
  (svn_cl__get_log_message): Adjust caller of
   svn_client_get_log_message_templates_for_commit_items(): Check the number
   of hash entries instead of checking the returned hash against NULL.

* subversion/tests/libsvn_client/client-test.c
  (test_log_message_templates): Rename to ...
  (test_log_message_template): .. this and re-implement the test to use
   the changed API.

Modified:
    subversion/branches/log-message-templates/subversion/include/svn_client.h
    subversion/branches/log-message-templates/subversion/libsvn_client/commit_util.c
    subversion/branches/log-message-templates/subversion/svn/util.c
    subversion/branches/log-message-templates/subversion/tests/libsvn_client/client-test.c

Modified: subversion/branches/log-message-templates/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-message-templates/subversion/include/svn_client.h?rev=1624039&r1=1624038&r2=1624039&view=diff
==============================================================================
--- subversion/branches/log-message-templates/subversion/include/svn_client.h (original)
+++ subversion/branches/log-message-templates/subversion/include/svn_client.h Wed Sep 10 15:46:10
2014
@@ -2276,29 +2276,55 @@ svn_client_commit(svn_client_commit_info
                   svn_client_ctx_t *ctx,
                   apr_pool_t *pool);
 
-/* Given a list of absolute paths or URLs, set @a *log_message_templates to
- * a hash table containing one or more log message templates obtained from
- * svn:log-message properties applicable to these paths or URLs.
- * Set it to @c NULL if no log message template found.
- * The hash table is keyed by paths relative to the repository root.
- * Each path in this list of keys contributes a log message template.
- * The value for each key in the table is a 'const char *' log template.
+/* Given an absolute path or a URL, set @a *log_message_template to
+ * a log message template applicable to the path or URL.
  * 
- * Allocate @a *log_message_templates in @a result_pool.
- * Use @a scratch_pool for temporary allocations.
+ * Set @a *defining_repos_relpath to the path (relative to the repository
+ * root) on which the svn:log-message property which defines the log
+ * message template is set.
+ *
+ * If no log message templates is found, both @a *log_message_template
+ * and @a *defining_repos_relpath will be set to @c NULL.
+ *
+ * If @a revision->kind is #svn_opt_revision_unspecified, then: get
+ * properties from the working copy if @a path_or_url is a working copy
+ * path, or from the repository head if @a path_or_url is a URL. Else get
+ * the log message templates as of @a revision. The actual node revision
+ * selected is determined by the path as it exists in @a peg_revision.
+ * If @a peg_revision->kind is #svn_opt_revision_unspecified, then
+ * it defaults to #svn_opt_revision_head for URLs or
+ * #svn_opt_revision_working for WC paths. Use the authentication
+ * baton in @a ctx for authentication if contacting the repository.
+ * If @a actual_revnum is not @c NULL, the actual revision number used
+ * for the fetch is stored in @a *actual_revnum.
+ * 
+ * Allocate @a *log_message_template and @a *defining_repos_relpath
+ * in @a result_pool. Use @a scratch_pool for temporary allocations.
  *
  * @since New in 1.9.
  */
 svn_error_t *
-svn_client_get_log_message_templates(apr_hash_t **log_message_templates,
-                                     const apr_array_header_t *paths_or_urls,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool);
-
-
-/* Like svn_client_get_log_message_templates(), but accepts an array of
- * commit items instead of an array of paths or URLs.
+svn_client_get_log_message_template(const char **log_message_template,
+                                    const char **defining_repos_relpath,
+                                    const char *path_or_url,
+                                    svn_opt_revision_t *peg_revision,
+                                    svn_opt_revision_t *revision,
+                                    svn_revnum_t *actual_revnum,
+                                    svn_client_ctx_t *ctx,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool);
+
+
+/* Like svn_client_get_log_message_template(), but accepts an array of
+ * commit items as input and returns multiple log message templates.
+ *
+ * Set @a *log_message_templates to a hash table containing log message
+ * templates obtained from svn:log-message properties applicable to the
+ * commit items. The hash table is keyed by paths relative to the repository
+ * root. Each path in this list of keys contributes a log message template.
+ * The value for each key in the table is a 'const char *' log template.
+ *
+ * If no log message templates are found, the hash table will be empty. 
  *
  * @since New in 1.9.
  */

Modified: subversion/branches/log-message-templates/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-message-templates/subversion/libsvn_client/commit_util.c?rev=1624039&r1=1624038&r2=1624039&view=diff
==============================================================================
--- subversion/branches/log-message-templates/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/log-message-templates/subversion/libsvn_client/commit_util.c Wed Sep
10 15:46:10 2014
@@ -453,150 +453,135 @@ harvest_committables(const char *local_a
 }
 
 svn_error_t *
-svn_client_get_log_message_templates(apr_hash_t **log_message_templates,
-                                     const apr_array_header_t *paths_or_urls,
-                                     svn_client_ctx_t *ctx,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool)
+svn_client_get_log_message_template(const char **log_message_template,
+                                    const char **defining_repos_relpath,
+                                    const char *path_or_url,
+                                    svn_opt_revision_t *peg_revision,
+                                    svn_opt_revision_t *revision,
+                                    svn_revnum_t *actual_revnum,
+                                    svn_client_ctx_t *ctx,
+                                    apr_pool_t *result_pool,
+                                    apr_pool_t *scratch_pool)
 {
-  int i;
+  apr_hash_t *props = NULL;
+  apr_array_header_t *inherited_props = NULL;
+  const svn_string_t *propval = NULL;
+  const char *defining_path_or_url = NULL;
   apr_pool_t *iterpool;
 
-  *log_message_templates = apr_hash_make(result_pool);
+  *log_message_template = NULL;
+  *defining_repos_relpath = NULL;
+
   iterpool = svn_pool_create(scratch_pool);
-  for (i = 0; i < paths_or_urls->nelts; i++)
+  while (TRUE)
     {
-      const char *path_or_url =
-        APR_ARRAY_IDX(paths_or_urls, i, const char *);
-      apr_hash_t *props = NULL;
-      apr_array_header_t *inherited_props = NULL;
-      const svn_string_t *propval = NULL;
-      const char *defining_path_or_url = NULL;
-      const char *defining_repos_relpath;
-      svn_opt_revision_t unspecified_rev;
-      
+      svn_error_t *err;
+
       svn_pool_clear(iterpool);
 
-      unspecified_rev.kind = svn_opt_revision_unspecified;
-      while (TRUE)
+      if (!svn_path_is_url(path_or_url))
+        SVN_ERR_ASSERT(svn_dirent_is_absolute(path_or_url));
+      err = svn_client_propget5(&props, &inherited_props,
+                                SVN_PROP_INHERITABLE_LOG_TEMPLATE,
+                                path_or_url,
+                                peg_revision,
+                                revision,
+                                actual_revnum,
+                                svn_depth_empty,
+                                NULL, /* changelists */
+                                ctx,
+                                scratch_pool, iterpool);
+
+      if (err && (err->apr_err == SVN_ERR_ENTRY_NOT_FOUND ||
+                  err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE ||
+                  err->apr_err == SVN_ERR_FS_NOT_FOUND ||
+                  err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY))
         {
-          svn_error_t *err;
-
-          if (!svn_path_is_url(path_or_url))
-            SVN_ERR_ASSERT(svn_dirent_is_absolute(path_or_url));
-          err = svn_client_propget5(&props, &inherited_props,
-                                    SVN_PROP_INHERITABLE_LOG_TEMPLATE,
-                                    path_or_url,
-                                    &unspecified_rev, /* peg_revision */
-                                    &unspecified_rev, /* revision */
-                                    NULL, /* actual_revnum */
-                                    svn_depth_empty,
-                                    NULL, /* changelists */
-                                    ctx,
-                                    iterpool, iterpool);
-
-          if (err && err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)
+          if (svn_path_is_url(path_or_url))
             {
-              if (svn_path_is_url(path_or_url))
+              /* When adding new URLs we must query their nearest
+               * existing parent for log templates. */
+              const char *repos_root_url;
+              const char *child_relpath;
+
+              SVN_ERR(svn_client_get_repos_root(&repos_root_url, NULL,
+                                                path_or_url, ctx,
+                                                iterpool, iterpool));
+
+              /* Check if we've already reached the repository root. */
+              child_relpath = svn_uri_skip_ancestor(repos_root_url,
+                                                    path_or_url,
+                                                    iterpool);
+              if (child_relpath && child_relpath[0] != '\0')
                 {
-                  /* When adding new URLs we must query their nearest
-                   * existing parent for log templates. */
-                  const char *repos_root_url;
-                  const char *child_relpath;
-
-                  SVN_ERR(svn_client_get_repos_root(&repos_root_url, NULL,
-                                                    path_or_url, ctx,
-                                                    iterpool, iterpool));
-
-                  /* Check if we've already reached the repository root. */
-                  child_relpath = svn_uri_skip_ancestor(repos_root_url,
-                                                        path_or_url,
-                                                        iterpool);
-                  if (child_relpath && child_relpath[0] != '\0')
-                    {
-                      /* We didn't reach the root yet, so step up. */
-                      path_or_url = svn_uri_dirname(path_or_url, scratch_pool);
-                      svn_error_clear(err);
-                      continue;
-                    }
-                  else
-                    return svn_error_trace(err);
+                  /* We didn't reach the root yet, so step up. */
+                  path_or_url = svn_uri_dirname(path_or_url, scratch_pool);
+                  svn_error_clear(err);
+                  continue;
                 }
               else
                 return svn_error_trace(err);
             }
-          else if (err && err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
+          else
             {
-              if (!svn_path_is_url(path_or_url))
-                {
-                  /* Unversioned paths in the commit target list are
-                   * possible during 'svn import'. Ignore them. */
-                   svn_error_clear(err);
-                   break;
-                }
-              else
-                return svn_error_trace(err);
+              /* Unversioned paths in the commit target list are
+               * possible during 'svn import'. Ignore them. */
+               svn_error_clear(err);
+               break;
             }
-          else
-            SVN_ERR(err);
-
-          /* We've got properties for PATH_OR_URL. */
-          break;
         }
+      else
+        SVN_ERR(err);
 
-      if (props == NULL && inherited_props == NULL)
-        continue;
+      /* We've got properties for PATH_OR_URL. */
+      break;
+    }
+  svn_pool_destroy(iterpool);
 
-      /* Check if the node itself has an svn:log-template property. */
-      if (props)
-        propval = svn_hash_gets(props, path_or_url);
-      if (propval)
-        {
-          defining_path_or_url = path_or_url;
-        }
-      else if (inherited_props && inherited_props->nelts)
-        {
-          /* Check if the node inherits an svn:log-template property. */
-          svn_prop_inherited_item_t *iprop =
-            APR_ARRAY_IDX(inherited_props,
-                          inherited_props->nelts - 1,
-                          svn_prop_inherited_item_t *);
-          propval = svn_hash_gets(iprop->prop_hash,
-                                  SVN_PROP_INHERITABLE_LOG_TEMPLATE);
-          defining_path_or_url = iprop->path_or_url;
-        }
+  if (props == NULL && inherited_props == NULL)
+    return SVN_NO_ERROR;
 
-      if (propval == NULL || defining_path_or_url == NULL)
-        continue;
+  /* Check if the node itself has an svn:log-template property. */
+  if (props)
+    propval = svn_hash_gets(props, path_or_url);
+  if (propval)
+    defining_path_or_url = path_or_url;
+  else if (inherited_props && inherited_props->nelts)
+    {
+      /* Check if the node inherits an svn:log-template property. */
+      svn_prop_inherited_item_t *iprop =
+        APR_ARRAY_IDX(inherited_props,
+                      inherited_props->nelts - 1,
+                      svn_prop_inherited_item_t *);
+      propval = svn_hash_gets(iprop->prop_hash,
+                              SVN_PROP_INHERITABLE_LOG_TEMPLATE);
+      defining_path_or_url = iprop->path_or_url;
+    }
 
-      if (svn_path_is_url(defining_path_or_url))
-        {
-          const char *repos_root_url;
+  if (propval == NULL || defining_path_or_url == NULL)
+    return SVN_NO_ERROR;
 
-          SVN_ERR(svn_client_get_repos_root(&repos_root_url, NULL,
-                                            defining_path_or_url, ctx,
-                                            iterpool, iterpool));
-          defining_repos_relpath =
-            svn_uri_skip_ancestor(repos_root_url, defining_path_or_url,
-                                  result_pool);
-        }
-      else
-        SVN_ERR(svn_wc__node_get_repos_info(NULL, &defining_repos_relpath,
-                                            NULL, NULL, ctx->wc_ctx,
-                                            defining_path_or_url,
-                                            result_pool, iterpool));
-
-      /* Embedded NUL characters in the log message template string
-       * terminate the template regardless of the actual value of
-       * propval->len. */
-      if (!svn_hash_gets(*log_message_templates, defining_repos_relpath))
-        svn_hash_sets(*log_message_templates, defining_repos_relpath,
-                      apr_pstrdup(result_pool, propval->data));
-    }
-  svn_pool_destroy(iterpool);
+  if (svn_path_is_url(defining_path_or_url))
+    {
+      const char *repos_root_url;
 
-  if (apr_hash_count(*log_message_templates) == 0)
-    *log_message_templates = NULL;
+      SVN_ERR(svn_client_get_repos_root(&repos_root_url, NULL,
+                                        defining_path_or_url, ctx,
+                                        scratch_pool, scratch_pool));
+      *defining_repos_relpath =
+        svn_uri_skip_ancestor(repos_root_url, defining_path_or_url,
+                              result_pool);
+    }
+  else
+    SVN_ERR(svn_wc__node_get_repos_info(NULL, defining_repos_relpath,
+                                        NULL, NULL, ctx->wc_ctx,
+                                        defining_path_or_url,
+                                        result_pool, scratch_pool));
+
+  /* Embedded NUL characters in the log message template string
+   * terminate the template regardless of the actual value of
+   * propval->len. */
+  *log_message_template = apr_pstrdup(result_pool, propval->data);
 
   return SVN_NO_ERROR;
 }
@@ -2110,37 +2095,61 @@ svn_client_get_log_message_templates_for
   apr_pool_t *result_pool,
   apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *paths_or_urls;
   int i;
+  apr_pool_t *iterpool;
 
-  paths_or_urls = apr_array_make(scratch_pool, commit_items->nelts,
-                                 sizeof (const char *));
+  *log_message_templates = apr_hash_make(result_pool);
+  iterpool = svn_pool_create(scratch_pool);
   for (i = 0; i < commit_items->nelts; i++)
     {
       svn_client_commit_item3_t *item;
+      const char *path_or_url;
+      const char *log_message_template;
+      const char *defining_repos_relpath;
+      svn_opt_revision_t revision;
+      svn_opt_revision_t peg_revision;
+
+      svn_pool_clear(iterpool);
 
       item = APR_ARRAY_IDX(commit_items, i, svn_client_commit_item3_t *);
       if (item->path)
-        APR_ARRAY_PUSH(paths_or_urls, const char *) = item->path;
+        path_or_url = item->path;
       else
-        APR_ARRAY_PUSH(paths_or_urls, const char *) = item->url;
-#if 0
-      /* ### If the item is being copied, we should also consider log
-       * ### message templates from the copy source. However, URL-URL
-       * ### copy commit items don't carry copyfrom info at present,
-       * ### so ignore copyfrom until this inconsistency is fixed.
-       *
-       * Using outdated log templates is not useful so look in the HEAD
-       * revision and ignore item->copyfrom_rev. */
+        path_or_url = item->url;
+
+      revision.kind = svn_opt_revision_unspecified;
+      peg_revision.kind = svn_opt_revision_unspecified;
+
+      SVN_ERR(svn_client_get_log_message_template(&log_message_template,
+                                                  &defining_repos_relpath,
+                                                  path_or_url, &peg_revision,
+                                                  &revision, NULL, ctx,
+                                                  iterpool, iterpool));
+      if (log_message_template)
+        svn_hash_sets(*log_message_templates,
+                      apr_pstrdup(result_pool, defining_repos_relpath),
+                      apr_pstrdup(result_pool, log_message_template));
+
+      /* For copies, also consider templates defined on the copy source. */
       if (item->state_flags & SVN_CLIENT_COMMIT_ITEM_IS_COPY)
-        APR_ARRAY_PUSH(paths_or_urls, const char *) = item->copyfrom_url;
-#endif
+        {
+          peg_revision.kind = svn_opt_revision_number;
+          peg_revision.value.number = item->copyfrom_rev;
+          SVN_ERR(svn_client_get_log_message_template(&log_message_template,
+                                                      &defining_repos_relpath,
+                                                      item->copyfrom_url,
+                                                      &peg_revision,
+                                                      &revision, NULL, ctx,
+                                                      iterpool, iterpool));
+          if (log_message_template &&
+              svn_hash_gets(*log_message_templates,
+                            defining_repos_relpath) == NULL)
+            svn_hash_sets(*log_message_templates,
+                          apr_pstrdup(result_pool, defining_repos_relpath),
+                          apr_pstrdup(result_pool, log_message_template));
+        }
     }
-
-  SVN_ERR(svn_client_get_log_message_templates(log_message_templates,
-                                               paths_or_urls, ctx,
-                                               result_pool,
-                                               scratch_pool));
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/log-message-templates/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-message-templates/subversion/svn/util.c?rev=1624039&r1=1624038&r2=1624039&view=diff
==============================================================================
--- subversion/branches/log-message-templates/subversion/svn/util.c (original)
+++ subversion/branches/log-message-templates/subversion/svn/util.c Wed Sep 10 15:46:10 2014
@@ -340,7 +340,7 @@ svn_cl__get_log_message(const char **log
   /* Set default message.  */
   SVN_ERR(svn_client_get_log_message_templates_for_commit_items(
             &log_message_templates, commit_items, lmb->ctx, pool, pool));
-  if (log_message_templates)
+  if (apr_hash_count(log_message_templates) > 0)
     {
       svn_stringbuf_t *template_text;
       apr_hash_index_t *hi;

Modified: subversion/branches/log-message-templates/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-message-templates/subversion/tests/libsvn_client/client-test.c?rev=1624039&r1=1624038&r2=1624039&view=diff
==============================================================================
--- subversion/branches/log-message-templates/subversion/tests/libsvn_client/client-test.c
(original)
+++ subversion/branches/log-message-templates/subversion/tests/libsvn_client/client-test.c
Wed Sep 10 15:46:10 2014
@@ -1058,7 +1058,7 @@ test_remote_only_status(const svn_test_o
 }
 
 static svn_error_t *
-test_log_message_templates(const svn_test_opts_t *opts, apr_pool_t *pool)
+test_log_message_template(const svn_test_opts_t *opts, apr_pool_t *pool)
 {
   const char *repos_url;
   const char *wc_path;
@@ -1074,11 +1074,16 @@ test_log_message_templates(const svn_tes
     { "A/D/G",  "A/D/G template\n" },
   };
   int i;
+  const char *template;
+  const char *defining_repos_relpath;
   svn_revnum_t revnum;
+  svn_revnum_t actual_revnum;
   svn_opt_revision_t rev;
-  apr_hash_t *returned_templates;
-  apr_array_header_t *paths_or_urls = apr_array_make(pool, 4,
-                                                     sizeof (const char *));
+  svn_opt_revision_t unspecified_rev;
+  svn_client_copy_source_t copy_source;
+  apr_array_header_t *copy_sources;
+  
+  unspecified_rev.kind = svn_opt_revision_unspecified;
 
   /* Create a filesytem and repository containing the Greek tree. */
   SVN_ERR(create_greek_repos(&repos_url, "test-log-message-templates",
@@ -1101,6 +1106,25 @@ test_log_message_templates(const svn_tes
                                       NULL, NULL, /* commit callback/baton */
                                       ctx, pool));
 
+  /* Copy A -> A_copy. */
+  copy_source.path = apr_pstrcat(pool, repos_url, "/A", SVN_VA_NULL);
+  rev.kind = svn_opt_revision_number;
+  rev.value.number = revnum;
+  copy_source.revision = &rev;
+  copy_source.peg_revision = &rev;
+  copy_sources = apr_array_make(pool, 1, sizeof (svn_client_copy_source_t *));
+  APR_ARRAY_PUSH(copy_sources, svn_client_copy_source_t *) = &copy_source;
+  SVN_ERR(svn_client_copy6(copy_sources,
+                           apr_pstrcat(pool, repos_url, "/A_copy",
+                                       SVN_VA_NULL),
+                           FALSE, /* copy_as_child */
+                           FALSE, /* make_parents */
+                           FALSE, /* ignore_externals */
+                           NULL, /* revprop_table */
+                           NULL, NULL, /* commit callback/baton */
+                           ctx, pool));
+  revnum++;
+
   /* Check out a working copy. */
   wc_path = svn_test_data_path("test-log-message-templates-wc", pool);
   SVN_ERR(svn_io_remove_dir2(wc_path, TRUE, NULL, NULL, pool));
@@ -1112,121 +1136,104 @@ test_log_message_templates(const svn_tes
                                FALSE, FALSE, ctx, pool));
 
   /* None of the templates apply to the repository root. */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = repos_url;
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates == NULL);
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              repos_url,
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_ASSERT(template == NULL);
+  SVN_TEST_ASSERT(defining_repos_relpath == NULL);
+  SVN_TEST_ASSERT(actual_revnum == revnum);
 
   /* Likewise, none of templates apply to the working copy root. */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = wc_path;
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates == NULL);
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              wc_path,
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_ASSERT(template == NULL);
+  SVN_TEST_ASSERT(defining_repos_relpath == NULL);
+  SVN_TEST_ASSERT(actual_revnum == revnum);
 
   /* Find the iota template via an absolute path. */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = svn_dirent_join(wc_path,
-                                                                "iota",
-                                                                pool);
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates);
-  SVN_TEST_ASSERT(apr_hash_count(returned_templates) == 1);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "iota"),
-                         templates[0].template);
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              svn_dirent_join(
+                                                wc_path, "iota", pool),
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_STRING_ASSERT(template, templates[0].template);
+  SVN_TEST_STRING_ASSERT(defining_repos_relpath, templates[0].repos_relpath);
+  SVN_TEST_ASSERT(actual_revnum == revnum);
 
   /* Find the iota template via a URL. */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = apr_pstrcat(pool, repos_url,
-                                                            "/", "iota",
-                                                            SVN_VA_NULL);
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates);
-  SVN_TEST_ASSERT(apr_hash_count(returned_templates) == 1);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "iota"),
-                         templates[0].template);
-
-  /* Find the iota template via both an absolute path and URL. */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = svn_dirent_join(wc_path,
-                                                                "iota",
-                                                                pool);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = apr_pstrcat(pool, repos_url,
-                                                            "/", "iota",
-                                                            SVN_VA_NULL);
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates);
-  SVN_TEST_ASSERT(apr_hash_count(returned_templates) == 1);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "iota"),
-                         templates[0].template);
-
-  /* Gather all templates using a mix of URLs and paths. */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = svn_dirent_join(wc_path,
-                                                                "iota",
-                                                                pool);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = apr_pstrcat(pool, repos_url,
-                                                            "/A",
-                                                            SVN_VA_NULL);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = svn_dirent_join_many(
-                                                  pool, wc_path, "A", "B",
-                                                  SVN_VA_NULL);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = apr_pstrcat(pool, repos_url,
-                                                            "/A/D/G",
-                                                            SVN_VA_NULL);
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates);
-  SVN_TEST_ASSERT(apr_hash_count(returned_templates) == 4);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "iota"),
-                         templates[0].template);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "A"),
-                         templates[1].template);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "A/B"),
-                         templates[2].template);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "A/D/G"),
-                         templates[3].template);
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              apr_pstrcat(pool, repos_url,
+                                                "/", "iota", SVN_VA_NULL),
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_STRING_ASSERT(template, templates[0].template);
+  SVN_TEST_STRING_ASSERT(defining_repos_relpath, templates[0].repos_relpath);
+  SVN_TEST_ASSERT(actual_revnum == revnum);
 
   /* A/D/G/pi inherits a log template from A/D/G */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = apr_pstrcat(pool, repos_url,
-                                                            "/A/D/G/pi",
-                                                            SVN_VA_NULL);
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates);
-  SVN_TEST_ASSERT(apr_hash_count(returned_templates) == 1);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "A/D/G"),
-                         templates[3].template);
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              apr_pstrcat(pool, repos_url,
+                                                "/A/D/G/pi", SVN_VA_NULL),
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_STRING_ASSERT(template, templates[3].template);
+  SVN_TEST_STRING_ASSERT(defining_repos_relpath, templates[3].repos_relpath);
+  SVN_TEST_ASSERT(actual_revnum == revnum);
 
   /* A/B has its own log template, A/D inherits a log template from A. */
-  apr_array_clear(paths_or_urls);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = apr_pstrcat(pool, repos_url,
-                                                            "/A/B",
-                                                            SVN_VA_NULL);
-  APR_ARRAY_PUSH(paths_or_urls, const char *) = apr_pstrcat(pool, repos_url,
-                                                            "/A/D",
-                                                            SVN_VA_NULL);
-  SVN_ERR(svn_client_get_log_message_templates(&returned_templates,
-                                               paths_or_urls,
-                                               ctx, pool, pool));
-  SVN_TEST_ASSERT(returned_templates);
-  SVN_TEST_ASSERT(apr_hash_count(returned_templates) == 2);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "A"),
-                         templates[1].template);
-  SVN_TEST_STRING_ASSERT(svn_hash_gets(returned_templates, "A/B"),
-                         templates[2].template);
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              apr_pstrcat(pool, repos_url,
+                                                "/A/B", SVN_VA_NULL),
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_STRING_ASSERT(template, templates[2].template);
+  SVN_TEST_STRING_ASSERT(defining_repos_relpath, templates[2].repos_relpath);
+  SVN_TEST_ASSERT(actual_revnum == revnum);
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              apr_pstrcat(pool, repos_url,
+                                                "/A/D", SVN_VA_NULL),
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_STRING_ASSERT(template, templates[1].template);
+  SVN_TEST_STRING_ASSERT(defining_repos_relpath, templates[1].repos_relpath);
+  SVN_TEST_ASSERT(actual_revnum == revnum);
+
+  /* A_copy has the same log template content as A */
+  SVN_ERR(svn_client_get_log_message_template(&template,
+                                              &defining_repos_relpath,
+                                              apr_pstrcat(pool, repos_url,
+                                                "/A_copy", SVN_VA_NULL),
+                                              &unspecified_rev,
+                                              &unspecified_rev,
+                                              &actual_revnum,
+                                              ctx, pool, pool));
+  SVN_TEST_STRING_ASSERT(template, templates[1].template);
+  SVN_TEST_STRING_ASSERT(defining_repos_relpath, "A_copy");
+  SVN_TEST_ASSERT(actual_revnum == revnum);
 
   return SVN_NO_ERROR;
 }
@@ -1255,8 +1262,8 @@ static struct svn_test_descriptor_t test
                        "test svn_client_suggest_merge_sources"),
     SVN_TEST_OPTS_PASS(test_remote_only_status,
                        "test svn_client_status6 with ignore_local_mods"),
-    SVN_TEST_OPTS_PASS(test_log_message_templates,
-                       "test svn_client_get_log_message_templates"),
+    SVN_TEST_OPTS_PASS(test_log_message_template,
+                       "test svn_client_get_log_message_template"),
     SVN_TEST_NULL
   };
 



Mime
View raw message