Author: rhuijben
Date: Sun May 8 02:48:33 2011
New Revision: 1100674
URL: http://svn.apache.org/viewvc?rev=1100674&view=rev
Log:
Simplify a lot of conditions in the adm crawler.
* subversion/libsvn_wc/adm_crawler.c
(report_revisions_and_depths): Use an abspath as argument instead of
calculating the abspath again. Rename path variable to show that it is a
relpath. Handle the file external condition before everything else.
Remove old obstruction check (which assumed that obstructed dirs
would be skipped anyway). Update check when a node should be available.
(find_base_rev): Remove function.
(svn_wc_crawl_revisions5): When a node is not present in BASE, directly
report that we don't know it instead of doing a lot of work and then
report that we don't know it.
Normalize target depth to infinity before using its value.
Update check when a node should be available.
Rename anchor depth to report depth and pass that as the value to compare
against to report_revisions_and_depths.
Just pass depth infinity for files and symlinks.
(depth unknown is not supported here).
Remove checks for values that can only be set in old error conditions.
Modified:
subversion/trunk/subversion/libsvn_wc/adm_crawler.c
Modified: subversion/trunk/subversion/libsvn_wc/adm_crawler.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_crawler.c?rev=1100674&r1=1100673&r2=1100674&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_crawler.c Sun May 8 02:48:33 2011
@@ -231,14 +231,15 @@ read_externals_info(svn_wc__db_t *db,
/* The recursive crawler that describes a mixed-revision working
copy to an RA layer. Used to initiate updates.
- This is a depth-first recursive walk of DIR_PATH under ANCHOR_ABSPATH,
- using DB. Look at each entry and check if its revision is different
- than DIR_REV. If so, report this fact to REPORTER. If an entry is
- missing from disk, report its absence to REPORTER. If an entry has
+ This is a depth-first recursive walk of DIR_ABSPATH using DB. Look
+ at each entry and check if its revision is different than DIR_REV.
+ If so, report this fact to REPORTER. If an entry is. If a node has
a different URL than expected, report that to REPORTER. If an
entry has a different depth than its parent, report that to
REPORTER.
+ Report DIR_ABSPATH to the reporter as REPORT_RELPATH.
+
Alternatively, if REPORT_EVERYTHING is set, then report all
children unconditionally.
@@ -276,8 +277,8 @@ read_externals_info(svn_wc__db_t *db,
passed to restore_file() helper. */
static svn_error_t *
report_revisions_and_depths(svn_wc__db_t *db,
- const char *anchor_abspath,
- const char *dir_path,
+ const char *dir_abspath,
+ const char *report_relpath,
svn_revnum_t dir_rev,
const char *dir_repos_relpath,
const char *dir_repos_root,
@@ -299,7 +300,6 @@ report_revisions_and_depths(svn_wc__db_t
void *notify_baton,
apr_pool_t *scratch_pool)
{
- const char *dir_abspath;
apr_hash_t *base_children;
apr_hash_t *dirents;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
@@ -310,7 +310,6 @@ report_revisions_and_depths(svn_wc__db_t
/* Get both the SVN Entries and the actual on-disk entries. Also
notice that we're picking up hidden entries too (read_children never
hides children). */
- dir_abspath = svn_dirent_join(anchor_abspath, dir_path, scratch_pool);
SVN_ERR(svn_wc__db_base_get_children_info(&base_children, db, dir_abspath,
scratch_pool, iterpool));
@@ -345,7 +344,8 @@ report_revisions_and_depths(svn_wc__db_t
hi = apr_hash_next(hi))
{
const char *child = svn__apr_hash_index_key(hi);
- const char *this_path, *this_abspath;
+ const char *this_report_relpath;
+ const char *this_abspath;
svn_boolean_t this_switched = FALSE;
struct svn_wc__db_base_info_t *ths = svn__apr_hash_index_val(hi);
@@ -357,9 +357,16 @@ report_revisions_and_depths(svn_wc__db_t
svn_pool_clear(iterpool);
/* Compute the paths and URLs we need. */
- this_path = svn_dirent_join(dir_path, child, iterpool);
+ this_report_relpath = svn_relpath_join(report_relpath, child, iterpool);
this_abspath = svn_dirent_join(dir_abspath, child, iterpool);
+ /*** File Externals **/
+ if (ths->update_root)
+ {
+ /* File externals are ... special. We ignore them. */;
+ continue;
+ }
+
/* First check for exclusion */
if (ths->status == svn_wc__db_status_excluded)
{
@@ -375,7 +382,7 @@ report_revisions_and_depths(svn_wc__db_t
path. We explicitly prohibit this situation in
svn_wc_crop_tree(). */
SVN_ERR(reporter->set_path(report_baton,
- this_path,
+ this_report_relpath,
dir_rev,
svn_depth_exclude,
FALSE,
@@ -388,7 +395,7 @@ report_revisions_and_depths(svn_wc__db_t
deleted, and server will respond properly. */
if (! report_everything)
SVN_ERR(reporter->delete_path(report_baton,
- this_path, iterpool));
+ this_report_relpath, iterpool));
}
continue;
}
@@ -406,7 +413,8 @@ report_revisions_and_depths(svn_wc__db_t
now available (an addition after a not-present state), or if
it is now authorized (change in authz for the absent item). */
if (! report_everything)
- SVN_ERR(reporter->delete_path(report_baton, this_path, iterpool));
+ SVN_ERR(reporter->delete_path(report_baton, this_report_relpath,
+ iterpool));
continue;
}
@@ -430,12 +438,9 @@ report_revisions_and_depths(svn_wc__db_t
db, this_abspath,
iterpool, iterpool));
- if (restore_files
- && wrk_status != svn_wc__db_status_added
- && wrk_status != svn_wc__db_status_deleted
- && wrk_status != svn_wc__db_status_excluded
- && wrk_status != svn_wc__db_status_not_present
- && wrk_status != svn_wc__db_status_absent)
+ if (wrk_status == svn_wc__db_status_normal
+ || wrk_status == svn_wc__db_status_copied
+ || wrk_status == svn_wc__db_status_moved_here)
{
svn_node_kind_t dirent_kind;
@@ -476,22 +481,8 @@ report_revisions_and_depths(svn_wc__db_t
if (ths->depth == svn_depth_unknown)
ths->depth = svn_depth_infinity;
- /* Obstructed nodes might report SVN_INVALID_REVNUM. Tweak it.
-
- ### it seems that obstructed nodes should be handled quite a
- ### bit differently. maybe reported as missing, like not-present
- ### or absent nodes? */
- if (!SVN_IS_VALID_REVNUM(ths->revnum))
- ths->revnum = dir_rev;
-
- /*** File Externals **/
- if (ths->update_root)
- {
- /* File externals are ... special. We ignore them. */;
- }
-
/*** Files ***/
- else if (ths->kind == svn_wc__db_kind_file ||
+ if (ths->kind == svn_wc__db_kind_file ||
ths->kind == svn_wc__db_kind_symlink)
{
if (report_everything)
@@ -499,7 +490,7 @@ report_revisions_and_depths(svn_wc__db_t
/* Report the file unconditionally, one way or another. */
if (this_switched)
SVN_ERR(reporter->link_path(report_baton,
- this_path,
+ this_report_relpath,
svn_path_url_add_component2(
dir_repos_root,
ths->repos_relpath, iterpool),
@@ -510,7 +501,7 @@ report_revisions_and_depths(svn_wc__db_t
iterpool));
else
SVN_ERR(reporter->set_path(report_baton,
- this_path,
+ this_report_relpath,
ths->revnum,
ths->depth,
FALSE,
@@ -521,7 +512,7 @@ report_revisions_and_depths(svn_wc__db_t
/* Possibly report a disjoint URL ... */
else if (this_switched)
SVN_ERR(reporter->link_path(report_baton,
- this_path,
+ this_report_relpath,
svn_path_url_add_component2(
dir_repos_root,
ths->repos_relpath, iterpool),
@@ -536,7 +527,7 @@ report_revisions_and_depths(svn_wc__db_t
|| ths->lock
|| dir_depth == svn_depth_empty)
SVN_ERR(reporter->set_path(report_baton,
- this_path,
+ this_report_relpath,
ths->revnum,
ths->depth,
FALSE,
@@ -567,7 +558,7 @@ report_revisions_and_depths(svn_wc__db_t
/* Report the dir unconditionally, one way or another... */
if (this_switched)
SVN_ERR(reporter->link_path(report_baton,
- this_path,
+ this_report_relpath,
svn_path_url_add_component2(
dir_repos_root,
ths->repos_relpath, iterpool),
@@ -579,7 +570,7 @@ report_revisions_and_depths(svn_wc__db_t
iterpool));
else
SVN_ERR(reporter->set_path(report_baton,
- this_path,
+ this_report_relpath,
ths->revnum,
ths->depth,
start_empty,
@@ -590,7 +581,7 @@ report_revisions_and_depths(svn_wc__db_t
{
/* ...or possibly report a disjoint URL ... */
SVN_ERR(reporter->link_path(report_baton,
- this_path,
+ this_report_relpath,
svn_path_url_add_component2(
dir_repos_root,
ths->repos_relpath, iterpool),
@@ -617,7 +608,7 @@ report_revisions_and_depths(svn_wc__db_t
depth-empty. Also describe shallow subdirs if we are
trying to set depth to infinity. */
SVN_ERR(reporter->set_path(report_baton,
- this_path,
+ this_report_relpath,
ths->revnum,
ths->depth,
start_empty,
@@ -637,8 +628,8 @@ report_revisions_and_depths(svn_wc__db_t
}
SVN_ERR(report_revisions_and_depths(db,
- anchor_abspath,
- this_path,
+ this_abspath,
+ this_report_relpath,
ths->revnum,
repos_relpath,
dir_repos_root,
@@ -665,67 +656,6 @@ report_revisions_and_depths(svn_wc__db_t
return SVN_NO_ERROR;
}
-/* Helper for svn_wc_crawl_revisions5() that finds a base revision for a node
- that doesn't have one itself. */
-static svn_error_t *
-find_base_rev(svn_revnum_t *base_rev,
- svn_wc__db_t *db,
- const char *local_abspath,
- const char *top_local_abspath,
- apr_pool_t *pool)
-{
- const char *op_root_abspath;
- svn_wc__db_status_t status;
- svn_boolean_t have_base;
-
- SVN_ERR(svn_wc__db_read_info(&status, NULL, base_rev, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- &have_base, NULL, NULL,
- db, local_abspath, pool, pool));
-
- if (SVN_IS_VALID_REVNUM(*base_rev))
- return SVN_NO_ERROR;
-
- if (have_base)
- return svn_error_return(
- svn_wc__db_base_get_info(NULL, NULL, base_rev, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL,
- db, local_abspath, pool, pool));
-
- if (status == svn_wc__db_status_added)
- {
- SVN_ERR(svn_wc__db_scan_addition(NULL, &op_root_abspath, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- db, local_abspath, pool, pool));
-
- return svn_error_return(
- find_base_rev(base_rev,
- db, svn_dirent_dirname(op_root_abspath, pool),
- top_local_abspath,
- pool));
- }
- else if (status == svn_wc__db_status_deleted)
- {
- const char *work_del_abspath;
- SVN_ERR(svn_wc__db_scan_deletion(NULL, NULL, &work_del_abspath,
- db, local_abspath, pool, pool));
-
- if (work_del_abspath != NULL)
- return svn_error_return(
- find_base_rev(base_rev,
- db, work_del_abspath,
- top_local_abspath,
- pool));
- }
-
- return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
- _("Can't retrieve base revision for %s"),
- svn_dirent_local_style(top_local_abspath, pool));
-}
-
/*------------------------------------------------------------------*/
/*** Public Interfaces ***/
@@ -754,13 +684,13 @@ svn_wc_crawl_revisions5(svn_wc_context_t
svn_revnum_t target_rev = SVN_INVALID_REVNUM;
svn_boolean_t start_empty;
svn_wc__db_status_t status;
- svn_wc__db_kind_t target_kind = svn_wc__db_kind_unknown;
- const char *repos_relpath=NULL, *repos_root_url=NULL;
- svn_depth_t target_depth = svn_depth_unknown;
- svn_wc__db_lock_t *target_lock = NULL;
+ svn_wc__db_kind_t target_kind;
+ const char *repos_relpath, *repos_root_url;
+ svn_depth_t target_depth;
+ svn_wc__db_lock_t *target_lock;
svn_node_kind_t disk_kind;
- svn_boolean_t explicit_rev;
svn_boolean_t had_props;
+ svn_depth_t report_depth;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
/* The first thing we do is get the base_rev from the working copy's
@@ -774,45 +704,26 @@ svn_wc_crawl_revisions5(svn_wc_context_t
db, local_abspath, scratch_pool,
scratch_pool);
- if (err)
+ if (err
+ || (status != svn_wc__db_status_normal
+ && status != svn_wc__db_status_incomplete))
{
- if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ if (err && err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
return svn_error_return(err);
svn_error_clear(err);
- had_props = FALSE;
- SVN_ERR(svn_wc__db_read_kind(&target_kind, db, local_abspath, TRUE,
- scratch_pool));
-
- if (target_kind == svn_wc__db_kind_file
- || target_kind == svn_wc__db_kind_symlink)
- status = svn_wc__db_status_absent; /* Crawl via parent dir */
- else
- status = svn_wc__db_status_not_present; /* As checkout */
- }
- else if (repos_root_url == NULL || repos_relpath == NULL)
- SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
- if (status == svn_wc__db_status_not_present
- || status == svn_wc__db_status_absent
- || (target_kind == svn_wc__db_kind_dir
- && status != svn_wc__db_status_normal
- && status != svn_wc__db_status_incomplete))
- {
- /* The target does not exist or is a local addition */
+ /* We don't know about this node, so all we have to do is tell
+ the reporter that we don't know this node.
- if (!SVN_IS_VALID_REVNUM(target_rev))
- target_rev = 0;
+ But first we have to start the report by sending some basic
+ information for the root. */
if (depth == svn_depth_unknown)
depth = svn_depth_infinity;
- SVN_ERR(reporter->set_path(report_baton, "", target_rev, depth,
- FALSE,
- NULL,
- scratch_pool));
+ SVN_ERR(reporter->set_path(report_baton, "", 0, depth, FALSE,
+ NULL, scratch_pool));
SVN_ERR(reporter->delete_path(report_baton, "", scratch_pool));
/* Finish the report, which causes the update editor to be
@@ -822,14 +733,13 @@ svn_wc_crawl_revisions5(svn_wc_context_t
return SVN_NO_ERROR;
}
- if (!SVN_IS_VALID_REVNUM(target_rev))
- {
- SVN_ERR(find_base_rev(&target_rev, db, local_abspath, local_abspath,
- scratch_pool));
- explicit_rev = TRUE;
- }
- else
- explicit_rev = FALSE;
+ if (! repos_relpath)
+ SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ if (target_depth == svn_depth_unknown)
+ target_depth = svn_depth_infinity;
start_empty = (status == svn_wc__db_status_incomplete);
if (depth_compatibility_trick
@@ -839,9 +749,6 @@ svn_wc_crawl_revisions5(svn_wc_context_t
start_empty = TRUE;
}
- if (target_depth == svn_depth_unknown)
- target_depth = svn_depth_infinity;
-
if (restore_files)
SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool));
else
@@ -852,10 +759,12 @@ svn_wc_crawl_revisions5(svn_wc_context_t
&& disk_kind == svn_node_none)
{
svn_wc__db_status_t wrk_status;
- err = svn_wc__db_read_info(&wrk_status, NULL, NULL, NULL, NULL, NULL,
+ svn_wc__db_kind_t wrk_kind;
+ err = svn_wc__db_read_info(&wrk_status, &wrk_kind, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL,
db, local_abspath,
scratch_pool, scratch_pool);
@@ -874,31 +783,29 @@ svn_wc_crawl_revisions5(svn_wc_context_t
db, local_abspath,
scratch_pool, scratch_pool));
- if (wrk_status != svn_wc__db_status_added
- && wrk_status != svn_wc__db_status_deleted
- && wrk_status != svn_wc__db_status_excluded
- && wrk_status != svn_wc__db_status_not_present
- && wrk_status != svn_wc__db_status_absent)
+ if (wrk_status == svn_wc__db_status_normal
+ || wrk_status == svn_wc__db_status_copied
+ || wrk_status == svn_wc__db_status_moved_here)
{
SVN_ERR(restore_node(wc_ctx->db, local_abspath,
- target_kind, use_commit_times,
+ wrk_kind, use_commit_times,
notify_func, notify_baton,
scratch_pool));
}
}
{
- svn_depth_t anchor_depth = target_depth;
+ report_depth = target_depth;
if (honor_depth_exclude
&& depth != svn_depth_unknown
&& depth < target_depth)
- anchor_depth = depth;
+ report_depth = depth;
/* The first call to the reporter merely informs it that the
top-level directory being updated is at BASE_REV. Its PATH
argument is ignored. */
- SVN_ERR(reporter->set_path(report_baton, "", target_rev, anchor_depth,
+ SVN_ERR(reporter->set_path(report_baton, "", target_rev, report_depth,
start_empty, NULL, scratch_pool));
}
if (target_kind == svn_wc__db_kind_dir)
@@ -913,7 +820,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
target_rev,
repos_relpath,
repos_root_url,
- target_depth,
+ report_depth,
reporter, report_baton,
restore_files, depth,
honor_depth_exclude,
@@ -933,7 +840,6 @@ svn_wc_crawl_revisions5(svn_wc_context_t
else if (target_kind == svn_wc__db_kind_file ||
target_kind == svn_wc__db_kind_symlink)
{
- svn_boolean_t skip_set_path = FALSE;
const char *parent_abspath, *base;
svn_wc__db_status_t parent_status;
const char *parent_repos_relpath;
@@ -969,16 +875,14 @@ svn_wc_crawl_revisions5(svn_wc_context_t
repos_relpath,
scratch_pool),
target_rev,
- target_depth,
+ svn_depth_infinity,
FALSE,
target_lock ? target_lock->token : NULL,
scratch_pool);
if (err)
goto abort_report;
- skip_set_path = TRUE;
}
-
- if (!skip_set_path && (explicit_rev || target_lock))
+ else if (target_lock)
{
/* If this entry is a file node, we just want to report that
node's revision. Since we are looking at the actual target
@@ -986,7 +890,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
directory), and that target is a file, we need to pass an
empty string to set_path. */
err = reporter->set_path(report_baton, "", target_rev,
- target_depth,
+ svn_depth_infinity,
FALSE,
target_lock ? target_lock->token : NULL,
scratch_pool);