diff options
Diffstat (limited to 'subversion/svn/status.c')
| -rw-r--r-- | subversion/svn/status.c | 65 | 
1 files changed, 31 insertions, 34 deletions
| diff --git a/subversion/svn/status.c b/subversion/svn/status.c index 9f1ad341bafb..9ab9c5926c55 100644 --- a/subversion/svn/status.c +++ b/subversion/svn/status.c @@ -138,37 +138,38 @@ generate_status_desc(enum svn_wc_status_kind status)  /* Make a relative path containing '..' elements as needed.     TARGET_ABSPATH shall be the absolute version of TARGET_PATH. -   TARGET_ABSPATH, TARGET_PATH and PATH shall be canonical. +   TARGET_ABSPATH, TARGET_PATH and LOCAL_ABSPATH shall be canonical     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.  */ +   allocations are made in SCRATCH_POOL. + +   Note that it is not possible to just join the resulting path to +   reconstruct the real path as the "../" paths are relative from +   a different base than the normal relative paths! + */  static const char *  make_relpath(const char *target_abspath,               const char *target_path, -             const char *path, +             const char *local_abspath,               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); +  const char *t_relpath; +  const char *p_relpath; -  if (err) -    { -      /* We probably got passed some invalid path. */ -      svn_error_clear(err); -      return apr_pstrdup(result_pool, path); -    } +#ifdef SVN_DEBUG +  SVN_ERR_ASSERT_NO_RETURN(svn_dirent_is_absolute(local_abspath)); +#endif -  relative = svn_dirent_skip_ancestor(target_abspath, abspath); -  if (relative) -    { -      return svn_dirent_join(target_path, relative, result_pool); -    } +  t_relpath = svn_dirent_skip_ancestor(target_abspath, local_abspath); + +  if (t_relpath) +    return svn_dirent_join(target_path, t_relpath, result_pool);    /* An example:     *  relative_to_path = /a/b/c @@ -180,17 +181,16 @@ make_relpath(const char *target_abspath,     *  path             = C:/wc     *  result           = C:/wc     */ -    /* Skip the common ancestor of both paths, here '/a'. */ -  la = svn_dirent_get_longest_ancestor(target_abspath, abspath, +  la = svn_dirent_get_longest_ancestor(target_abspath, local_abspath,                                         scratch_pool);    if (*la == '\0')      {        /* Nothing in common: E.g. C:/ vs F:/ on Windows */ -      return apr_pstrdup(result_pool, path); +      return apr_pstrdup(result_pool, local_abspath);      } -  relative = svn_dirent_skip_ancestor(la, target_abspath); -  path = svn_dirent_skip_ancestor(la, path); +  t_relpath = svn_dirent_skip_ancestor(la, target_abspath); +  p_relpath = svn_dirent_skip_ancestor(la, local_abspath);    /* In above example, we'd now have:     *  relative_to_path = b/c @@ -198,14 +198,14 @@ make_relpath(const char *target_abspath,    /* Count the elements of relative_to_path and prepend as many '..' elements     * to path. */ -  while (*relative) +  while (*t_relpath)      { -      svn_dirent_split(&relative, NULL, relative, -                       scratch_pool); +      t_relpath = svn_dirent_dirname(t_relpath, scratch_pool);        parent_dir_els = svn_dirent_join(parent_dir_els, "..", scratch_pool);      } -  return svn_dirent_join(parent_dir_els, path, result_pool); +  /* This returns a ../ style path relative from the status target */ +  return svn_dirent_join(parent_dir_els, p_relpath, result_pool);  } @@ -232,8 +232,6 @@ print_status(const char *target_abspath,    const char *moved_from_line = "";    const char *moved_to_line = ""; -  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. @@ -317,7 +315,7 @@ print_status(const char *target_abspath,                                      apr_psprintf(pool,                                                   _("swapped places with %s"),                                                   relpath), -                                    (char *)NULL); +                                    SVN_VA_NULL);      }    else if (status->moved_from_abspath || status->moved_to_abspath)      { @@ -332,7 +330,7 @@ print_status(const char *target_abspath,            moved_from_line = apr_pstrcat(pool, "\n        > ",                                          apr_psprintf(pool, _("moved from %s"),                                                       relpath), -                                        (char *)NULL); +                                        SVN_VA_NULL);          }        if (status->moved_to_abspath) @@ -344,7 +342,7 @@ print_status(const char *target_abspath,            moved_to_line = apr_pstrcat(pool, "\n        > ",                                        apr_psprintf(pool, _("moved to %s"),                                                     relpath), -                                      (char *)NULL); +                                      SVN_VA_NULL);          }      } @@ -487,10 +485,9 @@ svn_cl__print_status_xml(const char *target_abspath,      SVN_ERR(svn_wc_conflicted_p3(NULL, NULL, &tree_conflicted,                                   ctx->wc_ctx, local_abspath, 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); +                        "path", svn_dirent_local_style(path, pool), +                        SVN_VA_NULL);    att_hash = apr_hash_make(pool);    svn_hash_sets(att_hash, "item", @@ -560,7 +557,7 @@ svn_cl__print_status_xml(const char *target_abspath,                              generate_status_desc(combined_repos_status(status)),                              "props",                              generate_status_desc(status->repos_prop_status), -                            NULL); +                            SVN_VA_NULL);        if (status->repos_lock)          svn_cl__print_xml_lock(&sb, status->repos_lock, pool); | 
