summaryrefslogtreecommitdiff
path: root/subversion/svn/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/svn/status.c')
-rw-r--r--subversion/svn/status.c65
1 files changed, 31 insertions, 34 deletions
diff --git a/subversion/svn/status.c b/subversion/svn/status.c
index 9f1ad34..9ab9c59 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);