subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From phi...@apache.org
Subject svn commit: r1506041 - in /subversion/trunk/subversion: svn/cl.h svn/status-cmd.c svn/status.c tests/cmdline/stat_tests.py
Date Tue, 23 Jul 2013 13:41:16 GMT
Author: philip
Date: Tue Jul 23 13:41:15 2013
New Revision: 1506041

URL: http://svn.apache.org/r1506041
Log:
Fix issue 4398, relative path handling in status.

* subversion/svn/cl.h
  (svn_cl__print_status, svn_cl__print_status_xml): Replace cwd parameter
   with two target parameters.

* subversion/svn/status-cmd.c
  (struct status_baton): Replace cwd member with two target members.
  (struct status_cache): Add two target members.
  (print_status_normal_or_xml): Pass new parameters.
  (print_status): Cache target parameters.
  (svn_cl__status): Store target rather than cwd, use cached target
   parameters.

* subversion/svn/status.c
  (make_relpath): Replace relative parameter with two target parameters.
  (print_status): Pass new parameters.
  (svn_cl__print_status, svn_cl__print_status_xml): Replace cwd parameter
   with two target parameters.

* subversion/tests/cmdline/stat_tests.py
  (status_path_handling): Remove XFAIL.

Modified:
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/status-cmd.c
    subversion/trunk/subversion/svn/status.c
    subversion/trunk/subversion/tests/cmdline/stat_tests.py

Modified: subversion/trunk/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1506041&r1=1506040&r2=1506041&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Tue Jul 23 13:41:15 2013
@@ -441,12 +441,12 @@ svn_cl__time_cstring_to_human_cstring(co
    Increment *TEXT_CONFLICTS, *PROP_CONFLICTS, or *TREE_CONFLICTS if
    a conflict was encountered.
 
-   Use CWD_ABSPATH -- the absolute path of the current working
-   directory -- to shorten PATH into something relative to that
-   directory as necessary.
+   Use TARGET_ABSPATH and TARGET_PATH to shorten PATH into something
+   relative to the target as necessary.
 */
 svn_error_t *
-svn_cl__print_status(const char *cwd_abspath,
+svn_cl__print_status(const char *target_abspath,
+                     const char *target_path,
                      const char *path,
                      const svn_client_status_t *status,
                      svn_boolean_t suppress_externals_placeholders,
@@ -464,12 +464,12 @@ svn_cl__print_status(const char *cwd_abs
 /* Print STATUS for PATH in XML to stdout.  Use POOL for temporary
    allocations.
 
-   Use CWD_ABSPATH -- the absolute path of the current working
-   directory -- to shorten PATH into something relative to that
-   directory as necessary.
+   Use TARGET_ABSPATH and TARGET_PATH to shorten PATH into something
+   relative to the target as necessary.
  */
 svn_error_t *
-svn_cl__print_status_xml(const char *cwd_abspath,
+svn_cl__print_status_xml(const char *target_abspath,
+                         const char *target_path,
                          const char *path,
                          const svn_client_status_t *status,
                          svn_client_ctx_t *ctx,

Modified: subversion/trunk/subversion/svn/status-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/status-cmd.c?rev=1506041&r1=1506040&r2=1506041&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/status-cmd.c (original)
+++ subversion/trunk/subversion/svn/status-cmd.c Tue Jul 23 13:41:15 2013
@@ -51,7 +51,8 @@ struct status_baton
 {
   /* These fields all correspond to the ones in the
      svn_cl__print_status() interface. */
-  const char *cwd_abspath;
+  const char *target_abspath;
+  const char *target_path;
   svn_boolean_t suppress_externals_placeholders;
   svn_boolean_t detailed;
   svn_boolean_t show_last_committed;
@@ -77,6 +78,8 @@ struct status_baton
 struct status_cache
 {
   const char *path;
+  const char *target_abspath;
+  const char *target_path;
   svn_client_status_t *status;
 };
 
@@ -152,10 +155,11 @@ print_status_normal_or_xml(void *baton,
   struct status_baton *sb = baton;
 
   if (sb->xml_mode)
-    return svn_cl__print_status_xml(sb->cwd_abspath, path, status,
-                                    sb->ctx, pool);
+    return svn_cl__print_status_xml(sb->target_abspath, sb->target_path,
+                                    path, status, sb->ctx, pool);
   else
-    return svn_cl__print_status(sb->cwd_abspath, path, status,
+    return svn_cl__print_status(sb->target_abspath, sb->target_path,
+                                path, status,
                                 sb->suppress_externals_placeholders,
                                 sb->detailed,
                                 sb->show_last_committed,
@@ -239,6 +243,8 @@ print_status(void *baton,
       const char *cl_key = apr_pstrdup(sb->cl_pool, status->changelist);
       struct status_cache *scache = apr_pcalloc(sb->cl_pool, sizeof(*scache));
       scache->path = apr_pstrdup(sb->cl_pool, path);
+      scache->target_abspath = apr_pstrdup(sb->cl_pool, sb->target_abspath);
+      scache->target_path = apr_pstrdup(sb->cl_pool, sb->target_path);
       scache->status = svn_client_status_dup(status, sb->cl_pool);
 
       path_array =
@@ -303,7 +309,6 @@ svn_cl__status(apr_getopt_t *os,
                                   "mode"));
     }
 
-  SVN_ERR(svn_dirent_get_absolute(&(sb.cwd_abspath), "", scratch_pool));
   sb.suppress_externals_placeholders = (opt_state->quiet
                                         && (! opt_state->verbose));
   sb.detailed = (opt_state->verbose || opt_state->update);
@@ -328,6 +333,10 @@ svn_cl__status(apr_getopt_t *os,
 
       svn_pool_clear(iterpool);
 
+      SVN_ERR(svn_dirent_get_absolute(&(sb.target_abspath), target,
+                                      scratch_pool));
+      sb.target_path = target;
+
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
 
       if (opt_state->xml)
@@ -392,6 +401,8 @@ svn_cl__status(apr_getopt_t *os,
             {
               struct status_cache *scache =
                 APR_ARRAY_IDX(path_array, j, struct status_cache *);
+              sb.target_abspath = scache->target_abspath;
+              sb.target_path = scache->target_path;
               SVN_ERR(print_status_normal_or_xml(&sb, scache->path,
                                                  scache->status, scratch_pool));
             }

Modified: subversion/trunk/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/status.c?rev=1506041&r1=1506040&r2=1506041&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/status.c (original)
+++ subversion/trunk/subversion/svn/status.c Tue Jul 23 13:41:15 2013
@@ -137,69 +137,87 @@ generate_status_desc(enum svn_wc_status_
 }
 
 /* Make a relative path containing '..' elements as needed.
-   RELATIVE_TO_PATH must be the path to a directory (not a file!) and
-   TARGET_PATH must be the path to any file or directory. Both
-   RELATIVE_TO_PATH and TARGET_PATH must be based on the same parent path,
-   i.e. they can either both be absolute or they can both be relative to the
-   same parent directory. Both paths are expected to be canonical.
+   TARGET_ABSPATH shall be the absolute version of TARGET_PATH.
+   TARGET_ABSPATH, TARGET_PATH and PATH shall be canonical.
 
-   If above conditions are met, a relative path that leads to TARGET_ABSPATH
-   from RELATIVE_TO_PATH is returned, but there is no error checking involved.
+   If above conditions are met, a relative path that leads to PATH
+   from TARGET_PATH is returned, but there is no error checking involved.
 
-   The returned path is allocated from RESULT_POOL, all other allocations are
-   made in SCRATCH_POOL. */
+   The returned path is allocated from RESULT_POOL, all other
+   allocations are made in SCRATCH_POOL.  When the returned path is ""
+   the non-canonical value "." will be returned. */
 static const char *
-make_relpath(const char *relative_to_path,
+make_relpath(const char *target_abspath,
              const char *target_path,
+             const char *path,
              apr_pool_t *result_pool,
              apr_pool_t *scratch_pool)
 {
   const char *la;
   const char *parent_dir_els = "";
+  const char *abspath, *relative;
+  svn_error_t *err = svn_dirent_get_absolute(&abspath, path, scratch_pool);
+
+  if (err)
+    {
+      /* We probably got passed some invalid path. */
+      svn_error_clear(err);
+      return apr_pstrdup(result_pool, path);
+    }
+
+  relative = svn_dirent_skip_ancestor(target_abspath, abspath);
+  if (relative)
+    {
+      path = svn_dirent_join(target_path, relative, result_pool);
+      return *path ? path : ".";
+    }
 
   /* An example:
    *  relative_to_path = /a/b/c
-   *  target_path      = /a/x/y/z
+   *  path             = /a/x/y/z
    *  result           = ../../x/y/z
    *
    * Another example (Windows specific):
    *  relative_to_path = F:/wc
-   *  target_path      = C:/wc
+   *  path             = C:/wc
    *  result           = C:/wc
    */
 
   /* Skip the common ancestor of both paths, here '/a'. */
-  la = svn_dirent_get_longest_ancestor(relative_to_path, target_path,
+  la = svn_dirent_get_longest_ancestor(target_abspath, abspath,
                                        scratch_pool);
   if (*la == '\0')
     {
       /* Nothing in common: E.g. C:/ vs F:/ on Windows */
-      return apr_pstrdup(result_pool, target_path);
+      return apr_pstrdup(result_pool, path);
     }
-  relative_to_path = svn_dirent_skip_ancestor(la, relative_to_path);
-  target_path = svn_dirent_skip_ancestor(la, target_path);
+  relative = svn_dirent_skip_ancestor(la, target_abspath);
+  path = svn_dirent_skip_ancestor(la, path);
 
   /* In above example, we'd now have:
    *  relative_to_path = b/c
-   *  target_path      = x/y/z */
+   *  path             = x/y/z */
 
   /* Count the elements of relative_to_path and prepend as many '..' elements
-   * to target_path. */
-  while (*relative_to_path)
+   * to path. */
+  while (*relative)
     {
-      svn_dirent_split(&relative_to_path, NULL, relative_to_path,
+      svn_dirent_split(&relative, NULL, relative,
                        scratch_pool);
       parent_dir_els = svn_dirent_join(parent_dir_els, "..", scratch_pool);
     }
 
-  return svn_dirent_join(parent_dir_els, target_path, result_pool);
+  path = svn_dirent_join(parent_dir_els, path, result_pool);
+  return *path ? path : ".";
 }
 
 
 /* Print STATUS and PATH in a format determined by DETAILED and
    SHOW_LAST_COMMITTED. */
 static svn_error_t *
-print_status(const char *cwd_abspath, const char *path,
+print_status(const char *target_abspath,
+             const char *target_path,
+             const char *path,
              svn_boolean_t detailed,
              svn_boolean_t show_last_committed,
              svn_boolean_t repos_locks,
@@ -217,7 +235,7 @@ print_status(const char *cwd_abspath, co
   const char *moved_from_line = "";
   const char *moved_to_line = "";
 
-  path = make_relpath(cwd_abspath, path, pool, pool);
+  path = make_relpath(target_abspath, target_path, path, pool, pool);
 
   /* For historic reasons svn ignores the property status for added nodes, even
      if these nodes were copied and have local property changes.
@@ -295,7 +313,8 @@ print_status(const char *cwd_abspath, co
     {
       const char *relpath;
 
-      relpath = make_relpath(cwd_abspath, status->moved_from_abspath,
+      relpath = make_relpath(target_abspath, target_path,
+                             status->moved_from_abspath,
                              pool, pool);
       relpath = svn_dirent_local_style(relpath, pool);
       moved_from_line = apr_pstrcat(pool, "\n        > ",
@@ -310,7 +329,8 @@ print_status(const char *cwd_abspath, co
 
       if (status->moved_from_abspath)
         {
-          relpath = make_relpath(cwd_abspath, status->moved_from_abspath,
+          relpath = make_relpath(target_abspath, target_path,
+                                 status->moved_from_abspath,
                                  pool, pool);
           relpath = svn_dirent_local_style(relpath, pool);
           moved_from_line = apr_pstrcat(pool, "\n        > ",
@@ -321,7 +341,8 @@ print_status(const char *cwd_abspath, co
 
       if (status->moved_to_abspath)
         {
-          relpath = make_relpath(cwd_abspath, status->moved_to_abspath,
+          relpath = make_relpath(target_abspath, target_path,
+                                 status->moved_to_abspath,
                                  pool, pool);
           relpath = svn_dirent_local_style(relpath, pool);
           moved_to_line = apr_pstrcat(pool, "\n        > ",
@@ -448,7 +469,8 @@ print_status(const char *cwd_abspath, co
 
 
 svn_error_t *
-svn_cl__print_status_xml(const char *cwd_abspath,
+svn_cl__print_status_xml(const char *target_abspath,
+                         const char *target_path,
                          const char *path,
                          const svn_client_status_t *status,
                          svn_client_ctx_t *ctx,
@@ -467,7 +489,7 @@ svn_cl__print_status_xml(const char *cwd
     SVN_ERR(svn_wc_conflicted_p3(NULL, NULL, &tree_conflicted,
                                  ctx->wc_ctx, local_abspath, pool));
 
-  path = make_relpath(cwd_abspath, path, pool, pool);
+  path = make_relpath(target_abspath, target_path, path, pool, pool);
 
   svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
                         "path", svn_dirent_local_style(path, pool), NULL);
@@ -500,14 +522,16 @@ svn_cl__print_status_xml(const char *cwd
 
       if (status->moved_from_abspath)
         {
-          relpath = make_relpath(cwd_abspath, status->moved_from_abspath,
+          relpath = make_relpath(target_abspath, target_path,
+                                 status->moved_from_abspath,
                                  pool, pool);
           relpath = svn_dirent_local_style(relpath, pool);
           svn_hash_sets(att_hash, "moved-from", relpath);
         }
       if (status->moved_to_abspath)
         {
-          relpath = make_relpath(cwd_abspath, status->moved_to_abspath,
+          relpath = make_relpath(target_abspath, target_path,
+                                 status->moved_to_abspath,
                                  pool, pool);
           relpath = svn_dirent_local_style(relpath, pool);
           svn_hash_sets(att_hash, "moved-to", relpath);
@@ -552,7 +576,8 @@ svn_cl__print_status_xml(const char *cwd
 
 /* Called by status-cmd.c */
 svn_error_t *
-svn_cl__print_status(const char *cwd_abspath,
+svn_cl__print_status(const char *target_abspath,
+                     const char *target_path,
                      const char *path,
                      const svn_client_status_t *status,
                      svn_boolean_t suppress_externals_placeholders,
@@ -601,7 +626,8 @@ svn_cl__print_status(const char *cwd_abs
         return SVN_NO_ERROR;
     }
 
-  return print_status(cwd_abspath, svn_dirent_local_style(path, pool),
+  return print_status(target_abspath, target_path,
+                      svn_dirent_local_style(path, pool),
                       detailed, show_last_committed, repos_locks, status,
                       text_conflicts, prop_conflicts, tree_conflicts,
                       ctx, pool);

Modified: subversion/trunk/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/stat_tests.py?rev=1506041&r1=1506040&r2=1506041&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/stat_tests.py Tue Jul 23 13:41:15 2013
@@ -2093,7 +2093,6 @@ def move_update_timestamps(sbox):
   no_text_timestamp(sbox.ospath('A/B/E2/beta'))
 
 @Issue(4398)
-@XFail()
 def status_path_handling(sbox):
   "relative/absolute path handling"
 



Mime
View raw message