📄 adm_crawler.c
字号:
move on to the next entry. Later on, the update
editor will return an 'obstructed update' error. :) */
if (dirent_kind
&& (*dirent_kind != svn_node_file)
&& (! report_everything))
{
SVN_ERR (reporter->delete_path (report_baton, this_path,
iterpool));
continue;
}
/* If the item is missing from disk, and we're supposed to
restore missing things, and it isn't missing as a result
of a scheduling operation, then ... */
if (missing
&& restore_files
&& (current_entry->schedule != svn_wc_schedule_delete)
&& (current_entry->schedule != svn_wc_schedule_replace))
{
/* ... recreate file from text-base, and ... */
SVN_ERR (restore_file (this_full_path, dir_access,
use_commit_times, iterpool));
/* ... report the restoration to the caller. */
if (notify_func != NULL)
(*notify_func) (notify_baton,
this_full_path,
svn_wc_notify_restore,
svn_node_file,
NULL,
svn_wc_notify_state_unknown,
svn_wc_notify_state_unknown,
SVN_INVALID_REVNUM);
}
if (report_everything)
{
/* Report the file unconditionally, one way or another. */
if (strcmp (current_entry->url, this_url) != 0)
SVN_ERR (reporter->link_path (report_baton, this_path,
current_entry->url,
current_entry->revision,
FALSE, iterpool));
else
SVN_ERR (reporter->set_path (report_baton, this_path,
current_entry->revision,
FALSE, iterpool));
}
/* Possibly report a disjoint URL ... */
else if ((current_entry->schedule != svn_wc_schedule_add)
&& (current_entry->schedule != svn_wc_schedule_replace)
&& (strcmp (current_entry->url, this_url) != 0))
SVN_ERR (reporter->link_path (report_baton,
this_path,
current_entry->url,
current_entry->revision,
FALSE,
iterpool));
/* ... or perhaps just a differing revision. */
else if (current_entry->revision != dir_rev)
SVN_ERR (reporter->set_path (report_baton,
this_path,
current_entry->revision,
FALSE,
iterpool));
} /* end file case */
/*** Directories (in recursive mode) ***/
else if (current_entry->kind == svn_node_dir && recurse)
{
svn_wc_adm_access_t *subdir_access;
const svn_wc_entry_t *subdir_entry;
/* If a directory is missing from disk, we have no way to
recreate it locally, so report as missing and move
along. Again, don't bother if we're reporting
everything, because the dir is already missing on the server. */
if (missing)
{
if (! report_everything)
SVN_ERR (reporter->delete_path (report_baton, this_path,
iterpool));
continue;
}
/* No excuses here. If the user changed a versioned
directory into something else, the working copy is hosed.
It can't receive updates within this dir anymore. Throw
a real error. */
if (dirent_kind && (*dirent_kind != svn_node_dir))
{
return svn_error_createf
(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
_("The entry '%s' is no longer a directory; "
"remove the entry before updating"),
this_path);
}
/* We need to read the full entry of the directory from its
own "this dir", if available. */
SVN_ERR (svn_wc_adm_retrieve (&subdir_access, adm_access,
this_full_path, iterpool));
SVN_ERR (svn_wc_entry (&subdir_entry, this_full_path, subdir_access,
TRUE, iterpool));
if (report_everything)
{
/* Report the dir unconditionally, one way or another. */
if (strcmp (subdir_entry->url, this_url) != 0)
SVN_ERR (reporter->link_path (report_baton, this_path,
subdir_entry->url,
subdir_entry->revision,
subdir_entry->incomplete,
iterpool));
else
SVN_ERR (reporter->set_path (report_baton, this_path,
subdir_entry->revision,
subdir_entry->incomplete,
iterpool));
}
/* Possibly report a disjoint URL ... */
else if (strcmp (subdir_entry->url, this_url) != 0)
SVN_ERR (reporter->link_path (report_baton,
this_path,
subdir_entry->url,
subdir_entry->revision,
subdir_entry->incomplete,
iterpool));
/* ... or perhaps just a differing revision or incomplete subdir. */
else if (subdir_entry->revision != dir_rev
|| subdir_entry->incomplete)
SVN_ERR (reporter->set_path (report_baton,
this_path,
subdir_entry->revision,
subdir_entry->incomplete,
iterpool));
/* Recurse. */
SVN_ERR (report_revisions (adm_access, this_path,
subdir_entry->revision,
reporter, report_baton,
notify_func, notify_baton,
restore_files, recurse,
subdir_entry->incomplete,
use_commit_times,
traversal_info,
iterpool));
} /* end directory case */
} /* end main entries loop */
/* We're done examining this dir's entries, so free everything. */
svn_pool_destroy (subpool);
return SVN_NO_ERROR;
}
/*------------------------------------------------------------------*/
/*** Public Interfaces ***/
/* This is the main driver of the working copy state "reporter", used
for updates. */
svn_error_t *
svn_wc_crawl_revisions (const char *path,
svn_wc_adm_access_t *adm_access,
const svn_ra_reporter_t *reporter,
void *report_baton,
svn_boolean_t restore_files,
svn_boolean_t recurse,
svn_boolean_t use_commit_times,
svn_wc_notify_func_t notify_func,
void *notify_baton,
svn_wc_traversal_info_t *traversal_info,
apr_pool_t *pool)
{
svn_error_t *err = SVN_NO_ERROR;
const svn_wc_entry_t *entry;
svn_revnum_t base_rev = SVN_INVALID_REVNUM;
svn_boolean_t missing = FALSE;
const svn_wc_entry_t *parent_entry = NULL;
/* The first thing we do is get the base_rev from the working copy's
ROOT_DIRECTORY. This is the first revnum that entries will be
compared to. */
SVN_ERR (svn_wc_entry (&entry, path, adm_access, FALSE, pool));
if ((! entry) || ((entry->schedule == svn_wc_schedule_add)
&& (entry->kind == svn_node_dir)))
{
SVN_ERR (svn_wc_entry (&parent_entry,
svn_path_dirname (path, pool),
adm_access,
FALSE, pool));
base_rev = parent_entry->revision;
SVN_ERR (reporter->set_path (report_baton, "", base_rev,
entry ? entry->incomplete : TRUE,
pool));
SVN_ERR (reporter->delete_path (report_baton, "", pool));
/* Finish the report, which causes the update editor to be
driven. */
SVN_ERR (reporter->finish_report (report_baton, pool));
return SVN_NO_ERROR;
}
base_rev = entry->revision;
if (base_rev == SVN_INVALID_REVNUM)
{
SVN_ERR (svn_wc_entry (&parent_entry,
svn_path_dirname (path, pool),
adm_access,
FALSE, pool));
base_rev = parent_entry->revision;
}
/* 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, "", base_rev,
entry->incomplete , /* start_empty ? */
pool));
if (entry->schedule != svn_wc_schedule_delete)
{
apr_finfo_t info;
err = svn_io_stat (&info, path, APR_FINFO_MIN, pool);
if (err)
{
if (APR_STATUS_IS_ENOENT(err->apr_err))
missing = TRUE;
svn_error_clear (err);
err = NULL;
}
}
if (entry->kind == svn_node_dir)
{
if (missing)
{
/* Always report directories as missing; we can't recreate
them locally. */
err = reporter->delete_path (report_baton, "", pool);
if (err)
goto abort_report;
}
else
{
/* Recursively crawl ROOT_DIRECTORY and report differing
revisions. */
err = report_revisions (adm_access,
"",
base_rev,
reporter, report_baton,
notify_func, notify_baton,
restore_files, recurse,
entry->incomplete,
use_commit_times,
traversal_info,
pool);
if (err)
goto abort_report;
}
}
else if (entry->kind == svn_node_file)
{
const char *pdir, *bname;
if (missing && restore_files)
{
/* Recreate file from text-base. */
err = restore_file (path, adm_access, use_commit_times, pool);
if (err)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -