While debugging the status code I noticed that in some cases Subversion
will access and open local directories outside the requested target
directory.
This happens when:
- (one of) the target(s) is a directory
- the parent directory of the target is a working copy
When you run 'svn st -u wc/A', we create an edit_baton of type
(anchor='wc', target='A') in libsvn_client/status.c svn_client_status3.
A bit later in libsvn_wc/status.c make_dir_baton we make a dir_baton for
the anchor and open all its direct children (in get_dir_status)
non-recursively. So here it not only opens directory wc/A, but also
wc/iota, wc/newdir etc.
The overhead isn't big because of the non-recursiveness, but it's
overhead nonetheless and it makes it more difficult to add depth support.
Attached patch will fix this. Can anyone validate my assumptions before
I commit?
thx,
Lieven
[[[
When the target of 'svn status' is a versioned directory, use this directory
as anchor instead of opening the parent directory.
* subversion/libsvn_client/status.c
(svn_client_status3): try to open the target directory, If this fails
because
target is a file or an unversioned directory), fall back to opening the
parent directory instead.
]]]
Index: subversion/libsvn_client/status.c
===================================================================
--- subversion/libsvn_client/status.c (revision 24375)
+++ subversion/libsvn_client/status.c (working copy)
@@ -220,6 +220,8 @@
void *edit_baton, *set_locks_baton;
const svn_wc_entry_t *entry = NULL;
struct status_baton sb;
+ svn_error_t *err;
+
svn_revnum_t edit_revision = SVN_INVALID_REVNUM;
/* ### TODO(sd): This is a shim, we should use depth for real. */
svn_depth_t recurse = SVN_DEPTH_TO_RECURSE(depth);
@@ -228,11 +230,29 @@
sb.real_status_baton = status_baton;
sb.deleted_in_repos = FALSE;
- SVN_ERR(svn_wc_adm_open_anchor(&anchor_access, &target_access, &target,
- path, FALSE,
- SVN_DEPTH_TO_RECURSE(depth) ? -1 : 1,
- ctx->cancel_func, ctx->cancel_baton,
- pool));
+ /* Try to open the target directory. If the target is a file or an
+ unversioned directory, open the parent directory instead */
+ err = svn_wc_adm_open3(&anchor_access, NULL, path, FALSE,
+ SVN_DEPTH_TO_RECURSE(depth) ? -1 : 1,
+ ctx->cancel_func, ctx->cancel_baton,
+ pool);
+ if (err && err->apr_err == SVN_ERR_WC_NOT_DIRECTORY)
+ {
+ svn_error_clear(err);
+ SVN_ERR(svn_wc_adm_open_anchor(&anchor_access, &target_access, &target,
+ path, FALSE,
+ SVN_DEPTH_TO_RECURSE(depth) ? -1 : 1,
+ ctx->cancel_func, ctx->cancel_baton,
+ pool));
+ }
+ else if (!err)
+ {
+ target = "";
+ target_access = anchor_access;
+ }
+ else
+ return err;
+
anchor = svn_wc_adm_access_path(anchor_access);
if (depth == svn_depth_unknown)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Apr 3 14:44:03 2007