You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/10 20:06:33 UTC
svn commit: r984153 [21/39] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/
build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hu...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_crawler.c Tue Aug 10 18:06:17 2010
@@ -47,6 +47,7 @@
#include "translate.h"
#include "entries.h"
#include "lock.h"
+#include "workqueue.h"
#include "svn_private_config.h"
@@ -66,105 +67,33 @@ static svn_error_t *
restore_file(svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t use_commit_times,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
- svn_stream_t *src_stream;
- svn_boolean_t special;
- apr_time_t text_time;
-
- SVN_ERR(svn_wc__get_pristine_contents(&src_stream, db, local_abspath, pool,
- pool));
-
- SVN_ERR(svn_wc__get_special(&special, db, local_abspath, pool));
- if (special)
- {
- svn_stream_t *dst_stream;
-
- /* Copy the source into the destination to create the special file.
- The creation wil happen atomically. */
- SVN_ERR(svn_subst_create_specialfile(&dst_stream, local_abspath,
- pool, pool));
- /* ### need a cancel_func/baton */
- SVN_ERR(svn_stream_copy3(src_stream, dst_stream, NULL, NULL, pool));
- }
- else
- {
- svn_subst_eol_style_t style;
- const char *eol_str;
- apr_hash_t *keywords;
- const char *tmp_dir;
- const char *tmp_file;
- svn_stream_t *tmp_stream;
-
- SVN_ERR(svn_wc__get_eol_style(&style, &eol_str, db, local_abspath,
- pool, pool));
- SVN_ERR(svn_wc__get_keywords(&keywords, db, local_abspath, NULL, pool,
- pool));
-
- /* Get a temporary destination so we can use a rename to create the
- real destination atomically. */
- SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&tmp_dir, db, local_abspath,
- pool, pool));
- SVN_ERR(svn_stream_open_unique(&tmp_stream, &tmp_file, tmp_dir,
- svn_io_file_del_none, pool, pool));
-
- /* Wrap the (temp) destination stream with a translating stream. */
- if (svn_subst_translation_required(style, eol_str, keywords,
- FALSE /* special */,
- TRUE /* force_eol_check */))
- {
- tmp_stream = svn_subst_stream_translated(tmp_stream,
- eol_str,
- TRUE /* repair */,
- keywords,
- TRUE /* expand */,
- pool);
- }
-
- SVN_ERR(svn_stream_copy3(src_stream, tmp_stream, NULL, NULL, pool));
- /* ### need a cancel_func/baton */
- SVN_ERR(svn_io_file_rename(tmp_file, local_abspath, pool));
- }
+ const svn_skel_t *work_item;
- SVN_ERR(svn_wc__maybe_set_read_only(NULL, db, local_abspath, pool));
-
- /* If necessary, tweak the new working file's executable bit. */
- SVN_ERR(svn_wc__maybe_set_executable(NULL, db, local_abspath, pool));
+ SVN_ERR(svn_wc__wq_build_file_install(&work_item,
+ db, local_abspath,
+ NULL /* source_abspath */,
+ use_commit_times,
+ TRUE /* record_fileinfo */,
+ scratch_pool, scratch_pool));
+ /* ### we need an existing path for wq_add. not entirely WRI_ABSPATH yet */
+ SVN_ERR(svn_wc__db_wq_add(db,
+ svn_dirent_dirname(local_abspath, scratch_pool),
+ work_item, scratch_pool));
+
+ /* Run the work item immediately. */
+ SVN_ERR(svn_wc__wq_run(db, local_abspath,
+ NULL, NULL, /* ### nice to have cancel_func/baton */
+ scratch_pool));
/* Remove any text conflict */
SVN_ERR(svn_wc__internal_resolved_conflict(
db, local_abspath, svn_depth_empty, TRUE, NULL, FALSE,
svn_wc_conflict_choose_merged, NULL, NULL, NULL, NULL,
- pool));
-
- /* Possibly set timestamp to last-commit-time. */
- if (use_commit_times && (! special))
- {
- apr_time_t changed_date;
+ scratch_pool));
- SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL,
- NULL, NULL, NULL,
- NULL, &changed_date, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL,
- NULL, NULL, NULL,
- db, local_abspath,
- pool, pool));
-
- SVN_ERR(svn_io_set_file_affected_time(changed_date, local_abspath,
- pool));
-
- text_time = changed_date;
- }
- else
- {
- SVN_ERR(svn_io_file_affected_time(&text_time, local_abspath, pool));
- }
-
- /* Modify our entry's text-timestamp to match the working file. */
- return svn_error_return(
- svn_wc__db_op_set_last_mod_time(db, local_abspath, text_time, pool));
+ return SVN_NO_ERROR;
}
/* Try to restore LOCAL_ABSPATH of node type KIND and if successfull,
@@ -310,12 +239,12 @@ report_revisions_and_depths(svn_wc__db_t
svn_boolean_t depth_compatibility_trick,
svn_boolean_t report_everything,
svn_boolean_t use_commit_times,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
const char *dir_abspath;
const apr_array_header_t *children;
apr_hash_t *dirents;
- apr_pool_t *subpool = svn_pool_create(pool), *iterpool;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
int i;
const char *dir_repos_root, *dir_repos_relpath;
svn_depth_t dir_depth;
@@ -324,10 +253,10 @@ 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, subpool);
- SVN_ERR(svn_wc__db_read_children(&children, db, dir_abspath,
- subpool, subpool));
- SVN_ERR(svn_io_get_dir_filenames(&dirents, dir_abspath, subpool));
+ dir_abspath = svn_dirent_join(anchor_abspath, dir_path, scratch_pool);
+ SVN_ERR(svn_wc__db_base_get_children(&children, db, dir_abspath,
+ scratch_pool, iterpool));
+ SVN_ERR(svn_io_get_dir_filenames(&dirents, dir_abspath, scratch_pool));
/*** Do the real reporting and recursing. ***/
@@ -338,38 +267,35 @@ report_revisions_and_depths(svn_wc__db_t
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL,
db, dir_abspath,
- subpool, subpool));
+ scratch_pool, iterpool));
/* If the directory has no url, search its parents */
if (dir_repos_relpath == NULL)
SVN_ERR(svn_wc__db_scan_base_repos(&dir_repos_relpath, &dir_repos_root,
NULL, db, dir_abspath,
- subpool, subpool));
+ scratch_pool, iterpool));
/* If "this dir" has "svn:externals" property set on it, store its name
and depth in traversal_info. */
if (external_func)
{
SVN_ERR(read_traversal_info(db, dir_abspath, external_func,
- external_baton, dir_depth, subpool));
+ external_baton, dir_depth, iterpool));
}
/* Looping over current directory's SVN entries: */
- iterpool = svn_pool_create(subpool);
-
for (i = 0; i < children->nelts; ++i)
{
const char *child = APR_ARRAY_IDX(children, i, const char *);
const char *this_path, *this_abspath;
const char *this_repos_root_url, *this_repos_relpath;
- const char *this_original_repos_relpath;
svn_wc__db_status_t this_status;
svn_wc__db_kind_t this_kind;
- svn_revnum_t this_rev, this_base_rev;
+ svn_revnum_t this_rev;
svn_depth_t this_depth;
svn_wc__db_lock_t *this_lock;
- svn_boolean_t this_shadows_base, this_switched, replaced = FALSE;
-
+ svn_boolean_t this_switched;
+ svn_error_t *err;
/* Clear the iteration subpool here because the loop has a bunch
of 'continue' jump statements. */
@@ -379,15 +305,36 @@ report_revisions_and_depths(svn_wc__db_t
this_path = svn_dirent_join(dir_path, child, iterpool);
this_abspath = svn_dirent_join(dir_abspath, child, iterpool);
- SVN_ERR(svn_wc__db_read_info(&this_status, &this_kind, &this_rev,
- &this_repos_relpath, &this_repos_root_url,
- NULL, NULL, NULL, NULL, NULL, &this_depth,
- NULL, NULL, NULL, NULL,
- &this_original_repos_relpath,
- NULL, NULL, NULL, NULL, NULL,
- &this_shadows_base, NULL,
- &this_lock,
- db, this_abspath, iterpool, iterpool));
+ err = svn_wc__db_base_get_info(&this_status, &this_kind, &this_rev,
+ &this_repos_relpath, &this_repos_root_url,
+ NULL, NULL, NULL, NULL, NULL, &this_depth,
+ NULL, NULL, NULL, &this_lock,
+ db, this_abspath, iterpool, iterpool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ svn_error_clear(err);
+ else
+ SVN_ERR(err);
+
+ /* ### While still using parent stubs: Fetch info from the stub.
+ Handles the error case above */
+ {
+ svn_boolean_t not_present;
+
+ SVN_ERR(svn_wc__db_temp_is_dir_deleted(¬_present, &this_rev, db,
+ this_abspath, iterpool));
+
+ if (not_present || err)
+ this_status = svn_wc__db_status_not_present;
+
+ if (!SVN_IS_VALID_REVNUM(this_rev))
+ this_rev = dir_rev; /* Obstructed node */
+ } /* /Stub handling */
+
+ if (this_depth == svn_depth_unknown)
+ this_depth = svn_depth_infinity;
+
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(this_rev));
/* First check for exclusion */
if (this_status == svn_wc__db_status_excluded)
@@ -422,75 +369,38 @@ report_revisions_and_depths(svn_wc__db_t
continue;
}
- if (this_kind == svn_wc__db_kind_dir)
- {
- svn_revnum_t del_rev;
- SVN_ERR(svn_wc__db_temp_is_dir_deleted(&replaced, &del_rev,
- db, this_abspath,
- iterpool));
- }
-
/*** The Big Tests: ***/
-
- if (this_shadows_base)
+ if (this_status == svn_wc__db_status_absent ||
+ this_status == svn_wc__db_status_excluded ||
+ this_status == svn_wc__db_status_not_present)
{
- svn_wc__db_status_t this_base_status;
- SVN_ERR(svn_wc__db_base_get_info(&this_base_status, NULL,
- &this_base_rev,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, NULL,
- db, this_abspath,
- iterpool, iterpool));
-
- if (!replaced)
- replaced = (this_base_status == svn_wc__db_status_not_present);
- }
-
- {
- svn_boolean_t this_absent;
-
- if (replaced ||
- this_status == svn_wc__db_status_absent ||
- this_status == svn_wc__db_status_excluded ||
- this_status == svn_wc__db_status_not_present)
- {
- this_absent = TRUE;
- }
- else if (this_status == svn_wc__db_status_deleted && !this_shadows_base)
- this_absent = TRUE;
- else
- this_absent = FALSE;
-
- /* If the entry is 'deleted' or 'absent', make sure the server
- knows it's gone... */
- if (this_absent)
- {
- /* ...unless we're reporting everything, in which case we're
- going to report it missing later anyway. */
- if (! report_everything)
- SVN_ERR(reporter->delete_path(report_baton, this_path, iterpool));
- continue;
- }
- }
-
- /* From here on out, ignore any entry scheduled for addition */
- if ((this_status == svn_wc__db_status_added) ||
- (this_status == svn_wc__db_status_obstructed_add))
- {
- if (!replaced)
+ /* If the entry is 'deleted' or 'absent', make sure the server
+ knows it's gone...
+ ...unless we're reporting everything, in which case we're
+ going to report it missing later anyway. */
+ if (! report_everything)
+ SVN_ERR(reporter->delete_path(report_baton, this_path, iterpool));
continue;
-
- if (!this_shadows_base && this_original_repos_relpath)
- continue; /* Skip copy roots (and all children) */
- }
+ }
/* Is the entry on disk? */
if (apr_hash_get(dirents, child, APR_HASH_KEY_STRING) == NULL)
{
svn_boolean_t missing = FALSE;
- if (restore_files && this_status != svn_wc__db_status_deleted
- && !replaced)
+ svn_wc__db_status_t wrk_status;
+ svn_wc__db_kind_t wrk_kind;
+
+ SVN_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,
+ 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_obstructed_add
+ && wrk_status != svn_wc__db_status_obstructed_delete)
{
svn_node_kind_t dirent_kind;
@@ -503,7 +413,7 @@ report_revisions_and_depths(svn_wc__db_t
if (dirent_kind == svn_node_none)
{
svn_boolean_t restored;
- SVN_ERR(restore_node(&restored, db, this_abspath, this_kind,
+ SVN_ERR(restore_node(&restored, db, this_abspath, wrk_kind,
use_commit_times, notify_func,
notify_baton, iterpool));
@@ -514,11 +424,11 @@ report_revisions_and_depths(svn_wc__db_t
else
missing = TRUE;
- /* 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 && this_kind == svn_wc__db_kind_dir
+ /* If a node is still missing from disk here, 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 && wrk_kind == svn_wc__db_kind_dir
&& (depth > svn_depth_files || depth == svn_depth_unknown))
{
if (! report_everything)
@@ -546,32 +456,19 @@ report_revisions_and_depths(svn_wc__db_t
this_switched = FALSE;
}
- if (this_depth == svn_depth_unknown)
- this_depth = svn_depth_infinity;
-
- if (this_rev == SVN_INVALID_REVNUM)
- {
- /* For added and replaced nodes use their base revision
- in reports */
- this_rev = this_shadows_base ? this_base_rev : dir_rev;
- }
-
/*** Files ***/
if (this_kind == svn_wc__db_kind_file ||
this_kind == svn_wc__db_kind_symlink)
{
- const char *url = NULL;
-
- if (this_switched)
- url = svn_path_url_add_component2(dir_repos_root, this_repos_relpath, iterpool);
-
if (report_everything)
{
/* Report the file unconditionally, one way or another. */
if (this_switched)
SVN_ERR(reporter->link_path(report_baton,
this_path,
- url,
+ svn_path_url_add_component2(
+ dir_repos_root,
+ this_repos_relpath, iterpool),
this_rev,
this_depth,
FALSE,
@@ -588,10 +485,12 @@ report_revisions_and_depths(svn_wc__db_t
}
/* Possibly report a disjoint URL ... */
- else if (this_switched && !this_shadows_base)
+ else if (this_switched)
SVN_ERR(reporter->link_path(report_baton,
this_path,
- url,
+ svn_path_url_add_component2(
+ dir_repos_root,
+ this_repos_relpath, iterpool),
this_rev,
this_depth,
FALSE,
@@ -616,14 +515,8 @@ report_revisions_and_depths(svn_wc__db_t
&& (depth > svn_depth_files
|| depth == svn_depth_unknown))
{
- const char *url = NULL;
- svn_boolean_t start_empty;
svn_boolean_t is_incomplete = (this_status == svn_wc__db_status_incomplete);
-
- if (this_switched)
- url = svn_path_url_add_component2(dir_repos_root, this_repos_relpath, iterpool);
-
- start_empty = is_incomplete;
+ svn_boolean_t start_empty = is_incomplete;
if (depth_compatibility_trick
&& this_depth <= svn_depth_files
@@ -638,11 +531,14 @@ report_revisions_and_depths(svn_wc__db_t
if (this_switched)
SVN_ERR(reporter->link_path(report_baton,
this_path,
- url,
+ svn_path_url_add_component2(
+ dir_repos_root,
+ this_repos_relpath, iterpool),
this_rev,
this_depth,
start_empty,
- this_lock ? this_lock->token : NULL,
+ this_lock ? this_lock->token
+ : NULL,
iterpool));
else
SVN_ERR(reporter->set_path(report_baton,
@@ -658,7 +554,9 @@ report_revisions_and_depths(svn_wc__db_t
else if (this_switched)
SVN_ERR(reporter->link_path(report_baton,
this_path,
- url,
+ svn_path_url_add_component2(
+ dir_repos_root,
+ this_repos_relpath, iterpool),
this_rev,
this_depth,
start_empty,
@@ -704,7 +602,7 @@ report_revisions_and_depths(svn_wc__db_t
} /* end main entries loop */
/* We're done examining this dir's entries, so free everything. */
- svn_pool_destroy(subpool);
+ svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
@@ -788,106 +686,133 @@ svn_wc_crawl_revisions5(svn_wc_context_t
void *external_baton,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
svn_wc__db_t *db = wc_ctx->db;
svn_error_t *fserr, *err;
- svn_revnum_t base_rev = SVN_INVALID_REVNUM, target_rev;
+ svn_revnum_t target_rev = SVN_INVALID_REVNUM;
svn_boolean_t missing = FALSE;
svn_boolean_t start_empty;
svn_wc__db_status_t status;
- svn_wc__db_kind_t target_kind;
- const char *repos_relpath, *repos_root_url;
- svn_depth_t target_depth;
- svn_boolean_t replaced = FALSE;
- svn_wc__db_lock_t *target_lock;
- svn_boolean_t target_exists = TRUE;
+ svn_wc__db_kind_t target_kind = svn_wc__db_kind_unknown;
+ const char *repos_relpath=NULL, *repos_root=NULL;
+ svn_depth_t target_depth = svn_depth_unknown;
+ svn_wc__db_lock_t *target_lock = NULL;
+ svn_boolean_t explicit_rev;
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
/* 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. */
- err = svn_wc__db_read_info(&status, &target_kind, &target_rev,
- &repos_relpath, &repos_root_url,
- NULL, NULL, NULL, NULL, NULL,
- &target_depth, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &target_lock,
- db, local_abspath, pool, pool);
+ err = svn_wc__db_base_get_info(&status, &target_kind, &target_rev,
+ &repos_relpath, &repos_root,
+ NULL, NULL, NULL, NULL, NULL,
+ &target_depth, NULL, NULL, NULL,
+ &target_lock,
+ db, local_abspath, scratch_pool,
+ scratch_pool);
- if (err)
- {
- if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
- return svn_error_return(err);
+ {
+ svn_boolean_t has_base = TRUE;
- svn_error_clear(err);
- target_exists = FALSE;
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
+ return svn_error_return(err);
- /* Set output values of svn_wc__db_read_info to their empty values */
- status = svn_wc__db_status_not_present;
- target_kind = svn_wc__db_kind_unknown;
- target_rev = -1;
- repos_relpath = NULL;
- repos_root_url = NULL;
- target_depth = svn_depth_unknown;
- target_lock = NULL;
- }
+ svn_error_clear(err);
+ has_base = FALSE;
+ SVN_ERR(svn_wc__db_read_kind(&target_kind, db, local_abspath, TRUE,
+ scratch_pool));
- if (status == svn_wc__db_status_added)
- SVN_ERR(svn_wc__internal_is_replaced(&replaced, db, local_abspath, 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 */
+ }
- if (!target_exists ||
- (status == svn_wc__db_status_not_present) ||
- (target_kind == svn_wc__db_kind_dir && !replaced &&
- (status == svn_wc__db_status_added ||
- status == svn_wc__db_status_absent ||
- status == svn_wc__db_status_excluded ||
- status == svn_wc__db_status_obstructed ||
- status == svn_wc__db_status_obstructed_add ||
- status == svn_wc__db_status_obstructed_delete)))
- {
- /* Don't check the exclude flag for the target.
-
- If we report the target itself as excluded, the server will
- send us nothing about the target -- but we want to permit
- targets to be explicitly pulled in. For example, 'svn up A'
- should always work, even if its parent is svn_depth_empty or
- svn_depth_files, or even if A was explicitly excluded from a
- parent at svn_depth_immediates or svn_depth_infinity.
- Whatever the case, we want A back now. */
+ /* ### Check the parentstub if we don't find a BASE. But don't
+ do this if we already have the info we want or we break
+ some copy scenarios. */
+ if (!has_base && target_kind == svn_wc__db_kind_dir)
+ {
+ svn_boolean_t not_present;
+ svn_revnum_t rev = SVN_INVALID_REVNUM;
+ err = svn_wc__db_temp_is_dir_deleted(¬_present, &rev,
+ db, local_abspath, scratch_pool);
- if (!SVN_IS_VALID_REVNUM(base_rev))
- {
- const char *dir_abspath = svn_dirent_dirname(local_abspath, pool);
+ if (err && (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND
+ || err->apr_err == SVN_ERR_WC_NOT_WORKING_COPY))
+ {
+ svn_error_clear(err);
+ not_present = FALSE;
+ }
+ else
+ SVN_ERR(err);
- SVN_ERR(find_base_rev(&base_rev, db, dir_abspath, dir_abspath,
- pool));
- }
+ if (not_present)
+ status = svn_wc__db_status_not_present;
+
+ if (!SVN_IS_VALID_REVNUM(target_rev))
+ target_rev = rev;
+ }
+ }
+
+ if ((status == svn_wc__db_status_not_present)
+ || (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 */
- /* There aren't any versioned paths to crawl which are known to
- the repository. */
+ if (!SVN_IS_VALID_REVNUM(target_rev))
+ target_rev = 0;
- /* If no versioned path exists, we use the requested depth, which
- is the depth at which the new path should be brought in. Default
- to infinity if no explicit depth was given. */
if (depth == svn_depth_unknown)
depth = svn_depth_infinity;
- SVN_ERR(reporter->set_path(report_baton, "", base_rev, depth,
- status == svn_wc__db_status_incomplete,
- target_lock ? target_lock->token : NULL,
- pool));
- SVN_ERR(reporter->delete_path(report_baton, "", pool));
+ SVN_ERR(reporter->set_path(report_baton, "", target_rev, depth,
+ FALSE,
+ NULL,
+ scratch_pool));
+ SVN_ERR(reporter->delete_path(report_baton, "", scratch_pool));
/* Finish the report, which causes the update editor to be
driven. */
- return reporter->finish_report(report_baton, pool);
+ SVN_ERR(reporter->finish_report(report_baton, scratch_pool));
+
+ return SVN_NO_ERROR;
}
- base_rev = target_rev;
+ if (!repos_root || !repos_relpath)
+ {
+ err = svn_wc__db_scan_base_repos(&repos_relpath, &repos_root, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ svn_error_clear(err);
+ else
+ SVN_ERR(err);
- if (!SVN_IS_VALID_REVNUM(base_rev))
- SVN_ERR(find_base_rev(&base_rev, db, local_abspath, local_abspath, pool));
+ /* Ok, that leaves a local addition. Deleted and not existing nodes
+ are already handled. */
+ if (!repos_root || !repos_relpath)
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, &repos_relpath,
+ &repos_root, NULL, NULL, NULL, NULL,
+ NULL, db, local_abspath,
+ scratch_pool, scratch_pool));
+ }
+
+ 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;
start_empty = (status == svn_wc__db_status_incomplete);
if (depth_compatibility_trick
@@ -903,13 +828,13 @@ svn_wc_crawl_revisions5(svn_wc_context_t
/* 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, target_depth,
- start_empty, NULL, pool));
+ SVN_ERR(reporter->set_path(report_baton, "", target_rev, target_depth,
+ start_empty, NULL, scratch_pool));
if (status != svn_wc__db_status_deleted)
{
apr_finfo_t info;
- err = svn_io_stat(&info, local_abspath, APR_FINFO_MIN, pool);
+ err = svn_io_stat(&info, local_abspath, APR_FINFO_MIN, scratch_pool);
if (err)
{
if (APR_STATUS_IS_ENOENT(err->apr_err))
@@ -926,7 +851,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
err = restore_node(&restored, wc_ctx->db, local_abspath,
target_kind, use_commit_times,
notify_func, notify_baton,
- pool);
+ scratch_pool);
if (err)
goto abort_report;
@@ -941,7 +866,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
{
/* Report missing directories as deleted to retrieve them
from the repository. */
- err = reporter->delete_path(report_baton, "", pool);
+ err = reporter->delete_path(report_baton, "", scratch_pool);
if (err)
goto abort_report;
}
@@ -952,7 +877,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
err = report_revisions_and_depths(wc_ctx->db,
local_abspath,
"",
- base_rev,
+ target_rev,
reporter, report_baton,
external_func, external_baton,
notify_func, notify_baton,
@@ -961,7 +886,7 @@ svn_wc_crawl_revisions5(svn_wc_context_t
depth_compatibility_trick,
start_empty,
use_commit_times,
- pool);
+ scratch_pool);
if (err)
goto abort_report;
}
@@ -971,93 +896,82 @@ svn_wc_crawl_revisions5(svn_wc_context_t
target_kind == svn_wc__db_kind_symlink)
{
svn_boolean_t skip_set_path = FALSE;
-
- if (repos_relpath)
- {
- const char *parent_abspath, *base;
- svn_wc__db_status_t parent_status;
- const char *parent_repos_relpath;
-
- svn_dirent_split(local_abspath, &parent_abspath, &base, pool);
-
- /* We can assume a file is in the same repository as its parent
- directory, so we only look at the relpath. */
- err = svn_wc__db_read_info(&parent_status, NULL, NULL,
+ const char *parent_abspath, *base;
+ svn_wc__db_status_t parent_status;
+ const char *parent_repos_relpath;
+
+ svn_dirent_split(local_abspath, &parent_abspath, &base,
+ scratch_pool);
+
+ /* We can assume a file is in the same repository as its parent
+ directory, so we only look at the relpath. */
+ err = svn_wc__db_base_get_info(&parent_status, NULL, NULL,
&parent_repos_relpath, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- db, parent_abspath, pool, pool);
+ NULL, NULL,
+ db, parent_abspath,
+ scratch_pool, scratch_pool);
- if (err)
- goto abort_report;
+ if (err)
+ goto abort_report;
- if (!parent_repos_relpath &&
- parent_status == svn_wc__db_status_added)
- {
- err = svn_wc__db_scan_addition(NULL, NULL,
- &parent_repos_relpath, NULL,
- NULL, NULL, NULL, NULL, NULL,
- db, parent_abspath,
- pool, pool);
- }
- else if (!parent_repos_relpath)
- err = svn_wc__db_scan_base_repos(&parent_repos_relpath, NULL,
- NULL,
- db, parent_abspath,
- pool, pool);
+ if (!parent_repos_relpath)
+ err = svn_wc__db_scan_base_repos(&parent_repos_relpath, NULL,
+ NULL,
+ db, parent_abspath,
+ scratch_pool, scratch_pool);
+ if (err)
+ goto abort_report;
+
+ if (strcmp(repos_relpath,
+ svn_relpath_join(parent_repos_relpath, base,
+ scratch_pool)) != 0)
+ {
+ /* This file is disjoint with respect to its parent
+ directory. Since we are looking at the actual target of
+ the report (not some file in a subdirectory of a target
+ directory), and that target is a file, we need to pass an
+ empty string to link_path. */
+ err = reporter->link_path(report_baton,
+ "",
+ svn_path_url_add_component2(
+ repos_root,
+ repos_relpath,
+ scratch_pool),
+ target_rev,
+ target_depth,
+ FALSE,
+ target_lock ? target_lock->token : NULL,
+ scratch_pool);
if (err)
goto abort_report;
-
- if (strcmp(repos_relpath,
- svn_relpath_join(parent_repos_relpath, base, pool)) != 0)
- {
- /* This file is disjoint with respect to its parent
- directory. Since we are looking at the actual target of
- the report (not some file in a subdirectory of a target
- directory), and that target is a file, we need to pass an
- empty string to link_path. */
- err = reporter->link_path(report_baton,
- "",
- svn_path_url_add_component2(
- repos_root_url,
- repos_relpath,
- pool),
- base_rev,
- target_depth,
- FALSE,
- target_lock ? target_lock->token : NULL,
- pool);
- if (err)
- goto abort_report;
- skip_set_path = TRUE;
- }
+ skip_set_path = TRUE;
}
- if (!skip_set_path && (target_rev != base_rev || target_lock))
+ if (!skip_set_path && (explicit_rev || 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
of the report (not some file in a subdirectory of a target
directory), and that target is a file, we need to pass an
empty string to set_path. */
- err = reporter->set_path(report_baton, "", base_rev,
+ err = reporter->set_path(report_baton, "", target_rev,
target_depth,
FALSE,
target_lock ? target_lock->token : NULL,
- pool);
+ scratch_pool);
if (err)
goto abort_report;
}
}
/* Finish the report, which causes the update editor to be driven. */
- return reporter->finish_report(report_baton, pool);
+ return reporter->finish_report(report_baton, scratch_pool);
abort_report:
/* Clean up the fs transaction. */
- if ((fserr = reporter->abort_report(report_baton, pool)))
+ if ((fserr = reporter->abort_report(report_baton, scratch_pool)))
{
fserr = svn_error_quick_wrap(fserr, _("Error aborting report"));
svn_error_compose(err, fserr);
@@ -1082,6 +996,7 @@ struct copying_stream_baton
};
+/* */
static svn_error_t *
read_handler_copy(void *baton, char *buffer, apr_size_t *len)
{
@@ -1092,6 +1007,7 @@ read_handler_copy(void *baton, char *buf
return svn_stream_write(btn->target, buffer, len);
}
+/* */
static svn_error_t *
close_handler_copy(void *baton)
{
@@ -1152,8 +1068,9 @@ svn_wc__internal_transmit_text_deltas(co
SVN_WC_TRANSLATE_TO_NF,
scratch_pool, scratch_pool));
- /* Alert the caller that we have created a temporary file that might
- need to be cleaned up, if he asked for one. */
+ /* If the caller wants a copy of the working file translated to
+ * repository-normal form, make the copy by tee-ing the stream and set
+ * *TEMPFILE to the path to it. */
if (tempfile)
{
const char *tmp_base;
@@ -1188,6 +1105,8 @@ svn_wc__internal_transmit_text_deltas(co
/* Compute delta against the pristine contents */
SVN_ERR(svn_wc__get_pristine_contents(&base_stream, db, local_abspath,
scratch_pool, scratch_pool));
+ if (base_stream == NULL)
+ base_stream = svn_stream_empty(scratch_pool);
SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL,
NULL, NULL, NULL,
@@ -1218,7 +1137,10 @@ svn_wc__internal_transmit_text_deltas(co
/* ### we should ALREADY have the checksum for pristine. */
SVN_ERR(svn_wc__get_pristine_contents(&p_stream, db, local_abspath,
- scratch_pool, scratch_pool));
+ scratch_pool, scratch_pool));
+ if (p_stream == NULL)
+ p_stream = svn_stream_empty(scratch_pool);
+
p_stream = svn_stream_checksummed2(p_stream, &p_checksum,
NULL, svn_checksum_md5, TRUE,
scratch_pool);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.c Tue Aug 10 18:06:17 2010
@@ -223,33 +223,28 @@ make_adm_subdir(const char *path,
/*** Syncing files in the adm area. ***/
-/* Rename a tmp text-base file to its real text-base name.
- The file had better already be closed. */
svn_error_t *
-svn_wc__sync_text_base(const char *path, apr_pool_t *pool)
+svn_wc__sync_text_base(const char *local_abspath,
+ const char *tmp_text_base_abspath,
+ apr_pool_t *pool)
{
const char *parent_path;
const char *base_name;
- const char *tmp_path;
const char *base_path;
- svn_dirent_split(path, &parent_path, &base_name, pool);
-
- /* Extend tmp name. */
- tmp_path = extend_with_adm_name(parent_path, SVN_WC__BASE_EXT, TRUE, pool,
- SVN_WC__ADM_TEXT_BASE, base_name, NULL);
+ svn_dirent_split(local_abspath, &parent_path, &base_name, pool);
/* Extend real name. */
base_path = extend_with_adm_name(parent_path, SVN_WC__BASE_EXT, FALSE, pool,
SVN_WC__ADM_TEXT_BASE, base_name, NULL);
/* Rename. */
- SVN_ERR(svn_io_file_rename(tmp_path, base_path, pool));
+ SVN_ERR(svn_io_file_rename(tmp_text_base_abspath, base_path, pool));
return svn_io_set_file_read_only(base_path, FALSE, pool);
}
svn_error_t *
-svn_wc__text_base_path(const char **result_path,
+svn_wc__text_base_path(const char **result_abspath,
svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t tmp,
@@ -260,19 +255,19 @@ svn_wc__text_base_path(const char **resu
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
svn_dirent_split(local_abspath, &newpath, &base_name, pool);
- *result_path = extend_with_adm_name(newpath,
- SVN_WC__BASE_EXT,
- tmp,
- pool,
- SVN_WC__ADM_TEXT_BASE,
- base_name,
- NULL);
+ *result_abspath = extend_with_adm_name(newpath,
+ SVN_WC__BASE_EXT,
+ tmp,
+ pool,
+ SVN_WC__ADM_TEXT_BASE,
+ base_name,
+ NULL);
return SVN_NO_ERROR;
}
svn_error_t *
-svn_wc__text_revert_path(const char **result_path,
+svn_wc__text_revert_path(const char **result_abspath,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *pool)
@@ -282,13 +277,13 @@ svn_wc__text_revert_path(const char **re
SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
svn_dirent_split(local_abspath, &newpath, &base_name, pool);
- *result_path = extend_with_adm_name(newpath,
- SVN_WC__REVERT_EXT,
- FALSE,
- pool,
- SVN_WC__ADM_TEXT_BASE,
- base_name,
- NULL);
+ *result_abspath = extend_with_adm_name(newpath,
+ SVN_WC__REVERT_EXT,
+ FALSE,
+ pool,
+ SVN_WC__ADM_TEXT_BASE,
+ base_name,
+ NULL);
return SVN_NO_ERROR;
}
@@ -303,6 +298,8 @@ svn_wc__get_revert_contents(svn_stream_t
{
const char *revert_base;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
SVN_ERR(svn_wc__text_revert_path(&revert_base, db, local_abspath,
scratch_pool));
@@ -320,11 +317,11 @@ svn_wc__get_revert_contents(svn_stream_t
svn_error_t *
svn_wc__prop_path(const char **prop_path,
const char *path,
- svn_wc__db_kind_t kind,
+ svn_wc__db_kind_t node_kind,
svn_wc__props_kind_t props_kind,
apr_pool_t *pool)
{
- if (kind == svn_wc__db_kind_dir)
+ if (node_kind == svn_wc__db_kind_dir)
{
static const char * names[] = {
SVN_WC__ADM_DIR_PROP_BASE, /* svn_wc__props_base */
@@ -373,52 +370,6 @@ svn_wc__prop_path(const char **prop_path
/*** Opening and closing files in the adm area. ***/
-static svn_error_t *
-open_adm_file(svn_stream_t **stream,
- const char **selected_path,
- const char *path,
- const char *subdir,
- const char *fname,
- const char *extension,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_error_t *err;
-
- /* Extend with tmp name. */
- path = extend_with_adm_name(path, extension, TRUE, result_pool,
- subdir, fname, NULL);
-
- err = svn_stream_open_writable(stream, path, result_pool, scratch_pool);
-
- if (selected_path)
- *selected_path = path; /* note: built in result_pool */
-
- if (err && APR_STATUS_IS_EEXIST(err->apr_err))
- {
- /* Exclusive open failed, delete and retry */
- svn_error_clear(err);
- SVN_ERR(svn_io_remove_file2(path, FALSE, scratch_pool));
- err = svn_stream_open_writable(stream, path, result_pool, scratch_pool);
- }
-
- /* Examine the error from the first and/or second attempt at opening. */
- if (err && APR_STATUS_IS_ENOENT(err->apr_err))
- {
- /* If we receive a failure to open a file in our temporary directory,
- * it may be because our temporary directories aren't created.
- * Older SVN clients did not create these directories.
- * 'svn cleanup' will fix this problem.
- */
- err = svn_error_quick_wrap(err,
- _("Your .svn/tmp directory may be missing or "
- "corrupt; run 'svn cleanup' and try again"));
- }
-
- return svn_error_return(err);
-}
-
-
svn_error_t *
svn_wc__open_adm_stream(svn_stream_t **stream,
const char *dir_abspath,
@@ -428,6 +379,8 @@ svn_wc__open_adm_stream(svn_stream_t **s
{
const char *local_abspath;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+
local_abspath = svn_wc__adm_child(dir_abspath, fname, scratch_pool);
return svn_error_return(svn_stream_open_readonly(stream, local_abspath,
result_pool, scratch_pool));
@@ -436,25 +389,25 @@ svn_wc__open_adm_stream(svn_stream_t **s
svn_error_t *
svn_wc__open_writable_base(svn_stream_t **stream,
- const char **temp_base_path,
- const char *path,
- svn_boolean_t need_revert_base,
+ const char **temp_base_abspath,
+ svn_wc__db_t *db,
+ const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- const char *parent_path;
- const char *base_name;
-
- svn_dirent_split(path, &parent_path, &base_name, scratch_pool);
+ const char *temp_dir_abspath;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
- return open_adm_file(stream, temp_base_path,
- parent_path,
- SVN_WC__ADM_TEXT_BASE,
- base_name,
- need_revert_base
- ? SVN_WC__REVERT_EXT
- : SVN_WC__BASE_EXT,
- result_pool, scratch_pool);
+ /* Select a directory in which to put a WC-1-style temp text-base file. */
+ /* See update_editor.c:get_pristine_tee_stream() for the WC-NG way. */
+ SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir_abspath, db, local_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_stream_open_unique(stream,
+ temp_base_abspath,
+ temp_dir_abspath,
+ svn_io_file_del_none,
+ result_pool, scratch_pool));
+ return SVN_NO_ERROR;
}
@@ -462,6 +415,7 @@ svn_wc__open_writable_base(svn_stream_t
/*** Checking for and creating administrative subdirs. ***/
+/* */
static svn_error_t *
init_adm_tmp_area(const char *path, apr_pool_t *pool)
{
@@ -617,6 +571,8 @@ svn_wc__adm_destroy(svn_wc__db_t *db,
{
const char *adm_abspath;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(dir_abspath));
+
SVN_ERR(svn_wc__write_check(db, dir_abspath, scratch_pool));
/* Well, the coast is clear for blowing away the administrative
@@ -637,6 +593,8 @@ svn_wc__adm_cleanup_tmp_area(svn_wc__db_
{
const char *tmp_path;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(adm_abspath));
+
SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
/* Get the path to the tmp area, and blow it away. */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.h?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_files.h Tue Aug 10 18:06:17 2010
@@ -52,22 +52,27 @@ svn_boolean_t svn_wc__adm_area_exists(co
apr_pool_t *pool);
-/* Atomically rename a temporary text-base file to its canonical
- location. The tmp file should be closed already. */
+/* Atomically rename a temporary text-base file TMP_TEXT_BASE_ABSPATH to its
+ canonical location. LOCAL_ABSPATH is the path of the working file whose
+ text-base is to be moved. The tmp file should be closed already. */
svn_error_t *
-svn_wc__sync_text_base(const char *path, apr_pool_t *pool);
+svn_wc__sync_text_base(const char *local_abspath,
+ const char *tmp_text_base_path,
+ apr_pool_t *pool);
-/* Return an absolute path to LOCAL_ABSPATH's text-base file.
- If TMP is set, return a path to the tmp text-base file. */
+/* Set *RESULT_ABSPATH to the absolute path to LOCAL_ABSPATH's text-base file,
+ or, if TMP is set, to its temporary text-base file. */
svn_error_t *
-svn_wc__text_base_path(const char **result_path,
+svn_wc__text_base_path(const char **result_abspath,
svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t tmp,
apr_pool_t *pool);
-/* Return a readonly stream on the LOCAL_ABSPATH's base file. */
+/* Set *CONTENTS to a readonly stream on the LOCAL_ABSPATH's base file.
+ * For more detail, please see the description of
+ * svn_wc_get_pristine_contents2().*/
svn_error_t *
svn_wc__get_pristine_contents(svn_stream_t **contents,
svn_wc__db_t *db,
@@ -77,7 +82,7 @@ svn_wc__get_pristine_contents(svn_stream
-/* Return a readonly stream on the LOCAL_ABSPATH's revert file. */
+/* Set *CONTENTS to a readonly stream on the LOCAL_ABSPATH's revert file. */
svn_error_t *
svn_wc__get_revert_contents(svn_stream_t **contents,
svn_wc__db_t *db,
@@ -86,8 +91,7 @@ svn_wc__get_revert_contents(svn_stream_t
apr_pool_t *scratch_pool);
-/* Retrieve an absolute path to LOCAL_ABSPATH's revert file.
- If TMP is set, return a path to the tmp revert file. */
+/* Set *RESULT_ABSPATH to the absolute path to LOCAL_ABSPATH's revert file. */
svn_error_t *
svn_wc__text_revert_path(const char **result_abspath,
svn_wc__db_t *db,
@@ -100,7 +104,7 @@ svn_wc__text_revert_path(const char **re
and svn_node_file. */
svn_error_t *svn_wc__prop_path(const char **prop_path,
const char *path,
- svn_wc__db_kind_t kind,
+ svn_wc__db_kind_t node_kind,
svn_wc__props_kind_t props_kind,
apr_pool_t *pool);
@@ -116,16 +120,17 @@ svn_error_t *svn_wc__open_adm_stream(svn
apr_pool_t *scratch_pool);
-/* Open the normal or revert text base, associated with PATH, for writing.
- The selection is based on NEED_REVERT_BASE. The opened stream will be
- returned in STREAM and the selected path will be returned in,
- TEMP_BASE_PATH, and both will be allocated in RESULT_POOL. Any temporary
- allocations will be performed in SCRATCH_POOL. */
+/* Open a writable stream to a temporary (normal or revert) text base,
+ associated with the versioned file LOCAL_ABSPATH in DB. Set *STREAM to
+ the opened stream and *TEMP_BASE_ABSPATH to the path to the temporary
+ file, both allocated in RESULT_POOL. The temporary file will have an
+ arbitrary unique name, in contrast to the deterministic name that
+ svn_wc__text_base_path(tmp=TRUE) returns. */
svn_error_t *
svn_wc__open_writable_base(svn_stream_t **stream,
- const char **temp_base_path,
- const char *path,
- svn_boolean_t need_revert_base,
+ const char **temp_base_abspath,
+ svn_wc__db_t *db,
+ const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);