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 22:56:05 UTC
svn commit: r984206 [14/35] - in /subversion/branches/ignore-mergeinfo: ./
build/ build/generator/ build/generator/templates/ build/hudson/
build/hudson/jobs/subversion-1.6.x-solaris/
build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hudson/jobs/subvers...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c Tue Aug 10 20:55:56 2010
@@ -83,7 +83,11 @@ typedef struct
svn_boolean_t recurse;
svn_boolean_t no_unlock;
svn_boolean_t keep_changelist;
- const svn_checksum_t *checksum;
+
+ /* The pristine text checksum(s). Either or both may be present. */
+ const svn_checksum_t *md5_checksum;
+ const svn_checksum_t *sha1_checksum;
+
apr_hash_t *new_dav_cache;
} committed_queue_item_t;
@@ -107,7 +111,6 @@ tweak_entries(svn_wc__db_t *db,
svn_revnum_t new_rev,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
- svn_boolean_t remove_missing_dirs,
svn_depth_t depth,
apr_hash_t *exclude_paths,
apr_pool_t *pool)
@@ -202,14 +205,14 @@ tweak_entries(svn_wc__db_t *db,
long as this function is only called as a helper to
svn_wc__do_update_cleanup, since the update will already have
restored any missing items that it didn't want to delete. */
- if (remove_missing_dirs
- && svn_wc__adm_missing(db, child_abspath, iterpool))
+ if (svn_wc__adm_missing(db, child_abspath, iterpool))
{
if ( (status == svn_wc__db_status_added
|| status == svn_wc__db_status_obstructed_add)
&& !excluded)
{
- SVN_ERR(svn_wc__entry_remove(db, child_abspath, iterpool));
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, child_abspath,
+ iterpool));
if (notify_func)
{
@@ -235,7 +238,7 @@ tweak_entries(svn_wc__db_t *db,
{
SVN_ERR(tweak_entries(db, child_abspath, child_url,
new_rev, notify_func, notify_baton,
- remove_missing_dirs, depth_below_here,
+ depth_below_here,
exclude_paths, iterpool));
}
}
@@ -247,6 +250,7 @@ tweak_entries(svn_wc__db_t *db,
return SVN_NO_ERROR;
}
+
svn_error_t *
svn_wc__do_update_cleanup(svn_wc__db_t *db,
const char *local_abspath,
@@ -256,7 +260,6 @@ svn_wc__do_update_cleanup(svn_wc__db_t *
svn_revnum_t new_revision,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
- svn_boolean_t remove_missing_dirs,
apr_hash_t *exclude_paths,
apr_pool_t *pool)
{
@@ -272,7 +275,6 @@ svn_wc__do_update_cleanup(svn_wc__db_t *
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
db, local_abspath, pool, pool);
-
if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
{
svn_error_clear(err);
@@ -314,7 +316,7 @@ svn_wc__do_update_cleanup(svn_wc__db_t *
else if (kind == svn_wc__db_kind_dir)
{
SVN_ERR(tweak_entries(db, local_abspath, base_url, new_revision,
- notify_func, notify_baton, remove_missing_dirs,
+ notify_func, notify_baton,
depth, exclude_paths, pool));
}
else
@@ -326,26 +328,18 @@ svn_wc__do_update_cleanup(svn_wc__db_t *
}
-/* */
-static svn_error_t *
-process_deletion_postcommit(svn_wc__db_t *db,
- const char *adm_abspath,
- const char *local_abspath,
- svn_revnum_t new_revision,
- svn_boolean_t no_unlock,
- apr_pool_t *scratch_pool)
-{
-#ifdef NOT_NEEDED_NOW__CALLER_DOES_THIS
- SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
-#endif
-
- return svn_error_return(svn_wc__wq_add_deletion_postcommit(
- db, local_abspath, new_revision, no_unlock,
- scratch_pool));
-}
-
-
-/* CHECKSUM is the checksum of the new text base for LOCAL_ABSPATH, and must
+/* Queue work items that will finish a commit of the file or directory
+ * LOCAL_ABSPATH in DB:
+ * - queue the removal of any "revert-base" props and text files;
+ * - queue an update of the DB entry for this node
+ *
+ * ### The Pristine Store equivalent should be:
+ * - remember the old BASE_NODE and WORKING_NODE pristine text c'sums;
+ * - queue an update of the DB entry for this node (incl. updating the
+ * BASE_NODE c'sum and setting the WORKING_NODE c'sum to NULL);
+ * - queue deletion of the old pristine texts by the remembered checksums.
+ *
+ * CHECKSUM is the checksum of the new text base for LOCAL_ABSPATH, and must
* be provided if there is one, else NULL. */
static svn_error_t *
process_committed_leaf(svn_wc__db_t *db,
@@ -386,19 +380,54 @@ process_committed_leaf(svn_wc__db_t *db,
if (status == svn_wc__db_status_deleted
|| status == svn_wc__db_status_obstructed_delete)
{
- return svn_error_return(process_deletion_postcommit(
- db, adm_abspath, local_abspath,
- new_revnum, no_unlock,
+ return svn_error_return(svn_wc__wq_add_deletion_postcommit(
+ db, local_abspath, new_revnum, no_unlock,
scratch_pool));
}
+#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
+ /* Queue a removal of any "revert" properties now. These correspond to
+ the BASE properties, but hidden by new pristine props in WORKING.
+ Regardless, the commit will be installing new BASE props. */
+ /* ### this goes away once props are fully in the database */
+ {
+ const char *revert_props_abspath;
+ svn_skel_t *work_item;
+
+ /* ### this breaks the abstraction of svn_wc__props_delete, but
+ ### screw it. this is transitional code. */
+ /* ### what happens if the node changes its KIND? should be okay
+ ### since we disallow that today, and props should be in the DB
+ ### by the time that we DO allow that. */
+ SVN_ERR(svn_wc__prop_path(&revert_props_abspath, local_abspath, kind,
+ svn_wc__props_revert, scratch_pool));
+
+ SVN_ERR(svn_wc__wq_build_file_remove(&work_item,
+ db, revert_props_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_wq_add(db, adm_abspath, work_item, scratch_pool));
+ }
+#endif
+
/* ### this picks up file and symlink */
if (kind != svn_wc__db_kind_dir)
{
- /* If the props or text revert file exists it needs to be deleted when
- * the file is committed. */
- /* ### don't directories have revert props? */
- SVN_ERR(svn_wc__wq_remove_revert_files(db, local_abspath, scratch_pool));
+#ifdef SVN_EXPERIMENTAL_PRISTINE
+ /* The old pristine text will be dereferenced and (possibly) removed
+ from the pristine store when the new one replaces it. */
+#else
+ /* Queue a removal any "revert" text base now. */
+ {
+ const char *revert_abspath;
+ svn_skel_t *work_item;
+
+ SVN_ERR(svn_wc__text_revert_path(&revert_abspath, db, local_abspath,
+ scratch_pool));
+ SVN_ERR(svn_wc__wq_build_file_remove(&work_item, db, revert_abspath,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_wq_add(db, adm_abspath, work_item, scratch_pool));
+ }
+#endif
/* If we sent a delta (meaning: post-copy modification),
then this file will appear in the queue and so we should have
@@ -428,20 +457,34 @@ process_committed_leaf(svn_wc__db_t *db,
}
if (!no_unlock)
- SVN_ERR(svn_wc__loggy_delete_lock(db, adm_abspath,
- local_abspath, scratch_pool));
+ {
+ svn_skel_t *work_item;
- /* Set TMP_TEXT_BASE_ABSPATH to the new text base to be installed, if any. */
+ SVN_ERR(svn_wc__loggy_delete_lock(&work_item, db, adm_abspath,
+ local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_wq_add(db, adm_abspath, work_item, scratch_pool));
+ }
+
+#ifdef SVN_EXPERIMENTAL_PRISTINE
+ /* Set TMP_TEXT_BASE_ABSPATH to NULL. The new text base will be found in
+ the pristine store by its checksum. */
+ tmp_text_base_abspath = NULL;
+#else
+ /* Set TMP_TEXT_BASE_ABSPATH to the new text base to be installed, if any.
+ In effect, retrieve the temporary file that was laid down by
+ svn_wc__internal_transmit_text_deltas(). */
{
svn_node_kind_t new_base_kind;
- SVN_ERR(svn_wc__text_base_path(&tmp_text_base_abspath, db, local_abspath,
- TRUE, scratch_pool));
+ SVN_ERR(svn_wc__text_base_deterministic_tmp_path(&tmp_text_base_abspath,
+ db, local_abspath,
+ scratch_pool));
SVN_ERR(svn_io_check_path(tmp_text_base_abspath, &new_base_kind,
scratch_pool));
if (new_base_kind != svn_node_file)
tmp_text_base_abspath = NULL;
}
+#endif
SVN_ERR(svn_wc__wq_add_postcommit(db, local_abspath, tmp_text_base_abspath,
new_revnum,
@@ -463,7 +506,8 @@ svn_wc__process_committed_internal(svn_w
apr_hash_t *new_dav_cache,
svn_boolean_t no_unlock,
svn_boolean_t keep_changelist,
- const svn_checksum_t *checksum,
+ const svn_checksum_t *md5_checksum,
+ const svn_checksum_t *sha1_checksum,
const svn_wc_committed_queue_t *queue,
apr_pool_t *scratch_pool)
{
@@ -475,7 +519,8 @@ svn_wc__process_committed_internal(svn_w
new_revnum, new_date, rev_author,
new_dav_cache,
no_unlock, keep_changelist,
- checksum, scratch_pool));
+ md5_checksum, /* ### not yet: sha1_checksum, */
+ scratch_pool));
if (recurse && kind == svn_wc__db_kind_dir)
{
@@ -521,23 +566,9 @@ svn_wc__process_committed_internal(svn_w
if (status == svn_wc__db_status_excluded)
continue;
- /* Recurse, but only allow further recursion if the child is
- a directory. Pass NULL for NEW_DAV_CACHE, because the
- ones present in the current call are only applicable to
- this one committed item. */
- if (kind == svn_wc__db_kind_dir)
- {
- SVN_ERR(svn_wc__process_committed_internal(db, this_abspath,
- TRUE /* recurse */,
- new_revnum, new_date,
- rev_author,
- NULL,
- TRUE /* no_unlock */,
- keep_changelist, NULL,
- queue, iterpool));
- SVN_ERR(svn_wc__wq_run(db, this_abspath, NULL, NULL, iterpool));
- }
- else
+ md5_checksum = NULL;
+ sha1_checksum = NULL;
+ if (kind != svn_wc__db_kind_dir)
{
/* Suppress log creation for deleted entries in a replaced
directory. By the time any log we create here is run,
@@ -556,7 +587,6 @@ svn_wc__process_committed_internal(svn_w
continue;
}
- checksum = NULL;
if (queue != NULL)
{
const committed_queue_item_t *cqi
@@ -564,16 +594,29 @@ svn_wc__process_committed_internal(svn_w
APR_HASH_KEY_STRING);
if (cqi != NULL)
- checksum = cqi->checksum;
+ {
+ md5_checksum = cqi->md5_checksum;
+ sha1_checksum = cqi->sha1_checksum;
+ }
}
-
- SVN_ERR(process_committed_leaf(db, this_abspath,
- new_revnum,
- new_date, rev_author, NULL,
- TRUE /* no_unlock */,
- keep_changelist,
- checksum, iterpool));
}
+
+ /* Recurse. Pass NULL for NEW_DAV_CACHE, because the
+ ones present in the current call are only applicable to
+ this one committed item. */
+ SVN_ERR(svn_wc__process_committed_internal(db, this_abspath,
+ TRUE /* recurse */,
+ new_revnum, new_date,
+ rev_author,
+ NULL,
+ TRUE /* no_unlock */,
+ keep_changelist,
+ md5_checksum,
+ sha1_checksum,
+ queue, iterpool));
+
+ if (kind == svn_wc__db_kind_dir)
+ SVN_ERR(svn_wc__wq_run(db, this_abspath, NULL, NULL, iterpool));
}
svn_pool_destroy(iterpool);
@@ -626,7 +669,8 @@ svn_wc_queue_committed3(svn_wc_committed
const apr_array_header_t *wcprop_changes,
svn_boolean_t remove_lock,
svn_boolean_t remove_changelist,
- const svn_checksum_t *checksum,
+ const svn_checksum_t *md5_checksum,
+ const svn_checksum_t *sha1_checksum,
apr_pool_t *scratch_pool)
{
committed_queue_item_t *cqi;
@@ -645,7 +689,8 @@ svn_wc_queue_committed3(svn_wc_committed
cqi->recurse = recurse;
cqi->no_unlock = !remove_lock;
cqi->keep_changelist = !remove_changelist;
- cqi->checksum = checksum;
+ cqi->md5_checksum = md5_checksum;
+ cqi->sha1_checksum = sha1_checksum;
cqi->new_dav_cache = svn_wc__prop_array_to_hash(wcprop_changes, queue->pool);
apr_hash_set(queue->queue, local_abspath, APR_HASH_KEY_STRING, cqi);
@@ -696,7 +741,7 @@ svn_wc_process_committed_queue2(svn_wc_c
apr_time_t new_date;
if (rev_date)
- SVN_ERR(svn_time_from_cstring(&new_date, rev_date, scratch_pool));
+ SVN_ERR(svn_time_from_cstring(&new_date, rev_date, iterpool));
else
new_date = 0;
@@ -725,14 +770,15 @@ svn_wc_process_committed_queue2(svn_wc_c
cqi->new_dav_cache,
cqi->no_unlock,
cqi->keep_changelist,
- cqi->checksum, queue,
+ cqi->md5_checksum,
+ cqi->sha1_checksum, queue,
iterpool));
SVN_ERR(svn_wc__wq_run(wc_ctx->db, cqi->local_abspath, NULL, NULL,
iterpool));
}
- svn_hash__clear(queue->queue, scratch_pool);
+ svn_hash__clear(queue->queue, iterpool);
svn_pool_destroy(iterpool);
@@ -755,7 +801,8 @@ mark_tree_deleted(svn_wc__db_t *db,
int i;
/* Read the entries file for this directory. */
- SVN_ERR(svn_wc__db_read_children(&children, db, dir_abspath, pool, pool));
+ SVN_ERR(svn_wc__db_read_children(&children, db, dir_abspath,
+ pool, iterpool));
/* Mark each entry in the entries file. */
for (i = 0; i < children->nelts; i++)
@@ -787,7 +834,7 @@ mark_tree_deleted(svn_wc__db_t *db,
}
else
{
- SVN_ERR(svn_wc__db_temp_op_delete(db, child_abspath, pool));
+ SVN_ERR(svn_wc__db_temp_op_delete(db, child_abspath, iterpool));
}
/* Tell someone what we've done. */
@@ -889,13 +936,14 @@ erase_from_wc(svn_wc__db_t *db,
SVN_ERR(cancel_func(cancel_baton));
if (kind == svn_wc__db_kind_file || kind == svn_wc__db_kind_symlink)
- SVN_ERR(svn_io_remove_file2(local_abspath, TRUE, scratch_pool));
-
+ {
+ SVN_ERR(svn_io_remove_file2(local_abspath, TRUE, scratch_pool));
+ }
else if (kind == svn_wc__db_kind_dir)
/* This must be a directory or absent */
{
const apr_array_header_t *children;
- svn_wc__db_kind_t wc_kind;
+ svn_wc__db_kind_t db_kind;
apr_pool_t *iterpool;
apr_hash_t *versioned_dirs = apr_hash_make(scratch_pool);
apr_hash_t *unversioned;
@@ -903,10 +951,9 @@ erase_from_wc(svn_wc__db_t *db,
svn_error_t *err;
int i;
- SVN_ERR(svn_wc__db_read_kind(&wc_kind, db, local_abspath, TRUE,
+ SVN_ERR(svn_wc__db_read_kind(&db_kind, db, local_abspath, TRUE,
scratch_pool));
-
- if (wc_kind != svn_wc__db_kind_dir)
+ if (db_kind != svn_wc__db_kind_dir)
return SVN_NO_ERROR;
iterpool = svn_pool_create(scratch_pool);
@@ -923,7 +970,7 @@ erase_from_wc(svn_wc__db_t *db,
node_abspath = svn_dirent_join(local_abspath, name, iterpool);
- SVN_ERR(svn_wc__db_read_info(&status, &wc_kind, NULL, NULL, NULL,
+ SVN_ERR(svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
@@ -939,10 +986,10 @@ erase_from_wc(svn_wc__db_t *db,
continue; /* Not here */
/* ### We don't have to record dirs once we have a single database */
- if (wc_kind == svn_wc__db_kind_dir)
+ if (db_kind == svn_wc__db_kind_dir)
apr_hash_set(versioned_dirs, name, APR_HASH_KEY_STRING, name);
- SVN_ERR(erase_from_wc(db, node_abspath, wc_kind,
+ SVN_ERR(erase_from_wc(db, node_abspath, db_kind,
cancel_func, cancel_baton,
iterpool));
}
@@ -951,6 +998,8 @@ erase_from_wc(svn_wc__db_t *db,
err = svn_io_get_dirents2(&unversioned, local_abspath, scratch_pool);
if (err)
{
+ svn_pool_destroy(iterpool);
+
if (APR_STATUS_IS_ENOTDIR(err->apr_err) ||
APR_STATUS_IS_ENOENT(err->apr_err))
{
@@ -1064,8 +1113,9 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
if (kind == svn_wc__db_kind_dir)
{
- svn_revnum_t base_rev;
- SVN_ERR(svn_wc__db_temp_is_dir_deleted(&was_deleted, &base_rev,
+ svn_revnum_t unused_base_rev;
+
+ SVN_ERR(svn_wc__db_temp_is_dir_deleted(&was_deleted, &unused_base_rev,
db, local_abspath, pool));
if (was_add && !was_deleted)
@@ -1103,9 +1153,9 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
/* else
### Handle added directory that is deleted in parent_access
(was_deleted=TRUE). The current behavior is to just delete the
- directory with its administrative area inside, which is OK for WC-1.0,
- but when we move to a single database per working copy something
- must unversion the directory. */
+ directory with its administrative area inside, which is OK for
+ WC-1.0, but when we move to a single database per working copy
+ something must unversion the directory. */
}
if (kind != svn_wc__db_kind_dir || !was_add || was_deleted)
@@ -1187,19 +1237,6 @@ svn_wc__internal_get_ancestry(const char
}
-svn_error_t *
-svn_wc_get_ancestry2(const char **url,
- svn_revnum_t *rev,
- svn_wc_context_t *wc_ctx,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- return svn_error_return(
- svn_wc__internal_get_ancestry(url, rev, wc_ctx->db, local_abspath,
- result_pool, scratch_pool));
-}
-
/* Helper for mark_tree_copied(), handling the property juggling and
state changes for a single item LOCAL_ABSPATH (of kind LOCAL_KIND). */
static svn_error_t *
@@ -1218,12 +1255,23 @@ mark_item_copied(svn_wc__db_t *db,
SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
scratch_pool, scratch_pool));
tmp_entry.copied = TRUE;
- SVN_ERR(svn_wc__entry_modify2(db, local_abspath, kind, FALSE, &tmp_entry,
- SVN_WC__ENTRY_MODIFY_COPIED, scratch_pool));
+ SVN_ERR(svn_wc__entry_modify(db, local_abspath, kind, &tmp_entry,
+ SVN_WC__ENTRY_MODIFY_COPIED, scratch_pool));
/* Reinstall the pristine properties on WORKING */
+ /* ### this is all pretty crappy code anyways. not much of a problem
+ ### to pile on here.
+ ### thus... the node's original state may suggest there are no
+ ### pristine properties. in this case, we should say this (copied)
+ ### node has an empty set of properties. */
+ if (props == NULL)
+ props = apr_hash_make(scratch_pool);
SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath, props,
scratch_pool));
+
+ /* Remove now obsolete dav cache values. */
+ SVN_ERR(svn_wc__db_base_set_dav_cache(db, local_abspath, NULL,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -1234,14 +1282,21 @@ static svn_error_t *
mark_tree_copied(svn_wc__db_t *db,
const char *dir_abspath,
svn_wc__db_status_t dir_status,
+ const char *base_url,
apr_pool_t *pool)
{
apr_pool_t *iterpool = svn_pool_create(pool);
const apr_array_header_t *children;
int i;
+ /* Tweak "this_dir" */
+ SVN_ERR(svn_wc__tweak_entry(db, dir_abspath, svn_node_dir, FALSE,
+ base_url, SVN_INVALID_REVNUM,
+ FALSE /* allow_removal */, iterpool));
+
/* Read the entries file for this directory. */
- SVN_ERR(svn_wc__db_read_children(&children, db, dir_abspath, pool, pool));
+ SVN_ERR(svn_wc__db_read_children(&children, db, dir_abspath,
+ pool, iterpool));
/* Mark each entry in the entries file. */
for (i = 0; i < children->nelts; i++)
@@ -1250,17 +1305,17 @@ mark_tree_copied(svn_wc__db_t *db,
const char *child_abspath;
svn_wc__db_status_t child_status;
svn_wc__db_kind_t child_kind;
- svn_boolean_t hidden;
+ const char *child_url = NULL;
/* Clear our per-iteration pool. */
svn_pool_clear(iterpool);
- child_abspath = svn_dirent_join(dir_abspath, child_basename, iterpool);
+ /* Derive the new URL for the current (child) entry */
+ if (base_url)
+ child_url = svn_path_url_add_component2(base_url, child_basename,
+ iterpool);
- /* We exclude hidden nodes from this operation. */
- SVN_ERR(svn_wc__db_node_hidden(&hidden, db, child_abspath, iterpool));
- if (hidden)
- continue;
+ child_abspath = svn_dirent_join(dir_abspath, child_basename, iterpool);
SVN_ERR(svn_wc__db_read_info(&child_status, &child_kind, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -1268,29 +1323,55 @@ mark_tree_copied(svn_wc__db_t *db,
NULL, NULL, NULL, NULL, NULL, NULL,
db, child_abspath, iterpool, iterpool));
- /* Skip deleted items. */
- if ((child_status == svn_wc__db_status_deleted) ||
- (child_status == svn_wc__db_status_obstructed_delete))
+ /* ### "svn add" won't create excluded nodes, but "svn copy" will.
+ ### it copies all metadata, carrying over the excluded nodes. */
+
+ /* If a file, or deleted, excluded or absent dir, then tweak the
+ entry but don't recurse.
+
+ ### how does this translate into wc_db land? */
+ if (child_kind == svn_wc__db_kind_file
+ || child_status == svn_wc__db_status_not_present
+ || child_status == svn_wc__db_status_absent
+ || child_status == svn_wc__db_status_excluded)
+ {
+ if (child_kind == svn_wc__db_kind_dir)
+ SVN_ERR(svn_wc__tweak_entry(db, child_abspath, svn_node_dir,
+ TRUE /* parent_stub */,
+ child_url, SVN_INVALID_REVNUM,
+ TRUE /* allow_removal */,
+ iterpool));
+ else
+ SVN_ERR(svn_wc__tweak_entry(db, child_abspath, svn_node_file,
+ FALSE /* parent_stub */,
+ child_url, SVN_INVALID_REVNUM,
+ TRUE /* allow_removal */,
+ iterpool));
+ }
+
+ /* Skip deleted items, or otherwise "not really here" nodes. */
+ if (child_status == svn_wc__db_status_deleted
+ || child_status == svn_wc__db_status_obstructed_delete
+ || child_status == svn_wc__db_status_not_present
+ || child_status == svn_wc__db_status_absent
+ || child_status == svn_wc__db_status_excluded)
continue;
/* If this is a directory, recurse; otherwise, do real work. */
if (child_kind == svn_wc__db_kind_dir)
{
- SVN_ERR(mark_tree_copied(db, child_abspath, child_status, iterpool));
+ SVN_ERR(mark_tree_copied(db, child_abspath, child_status, child_url,
+ iterpool));
}
else
{
SVN_ERR(mark_item_copied(db, child_abspath, child_kind, iterpool));
}
-
- /* Remove now obsolete dav cache values. */
- SVN_ERR(svn_wc__db_base_set_dav_cache(db, child_abspath, NULL,
- iterpool));
}
/* Here's where we handle directories. */
- if (!((dir_status == svn_wc__db_status_deleted) ||
- (dir_status == svn_wc__db_status_obstructed_delete)))
+ if (dir_status != svn_wc__db_status_deleted
+ && dir_status != svn_wc__db_status_obstructed_delete)
{
SVN_ERR(mark_item_copied(db, dir_abspath, svn_wc__db_kind_dir,
iterpool));
@@ -1313,12 +1394,13 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
void *notify_baton,
apr_pool_t *pool)
{
- const char *parent_abspath, *base_name;
+ const char *parent_abspath;
+ const char *base_name;
const svn_wc_entry_t *parent_entry;
svn_wc_entry_t tmp_entry;
svn_boolean_t is_replace = FALSE;
svn_node_kind_t kind;
- apr_uint64_t modify_flags = 0;
+ int modify_flags;
svn_wc__db_t *db = wc_ctx->db;
svn_error_t *err;
svn_wc__db_status_t status;
@@ -1366,11 +1448,15 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
}
else
{
- svn_node_kind_t wc_kind;
+ svn_wc__db_kind_t on_disk;
SVN_ERR(err);
exists = TRUE;
+ on_disk = ((kind == svn_node_dir)
+ ? svn_wc__db_kind_dir
+ : svn_wc__db_kind_file);
+
switch (status)
{
case svn_wc__db_status_not_present:
@@ -1395,11 +1481,8 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
svn_dirent_local_style(local_abspath, pool));
}
- wc_kind = (db_kind == svn_wc__db_kind_dir) ? svn_node_dir
- : svn_node_file;
-
/* ### Remove this check once we are fully switched to one wcroot db */
- if (exists && wc_kind != kind)
+ if (exists && db_kind != on_disk)
{
/* ### todo: At some point, we obviously don't want to block
replacements where the node kind changes. When this
@@ -1416,8 +1499,11 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
}
}
- SVN_ERR(svn_wc__get_entry(&parent_entry, db, parent_abspath, FALSE,
- svn_node_dir, FALSE, pool, pool));
+ SVN_ERR(svn_wc__get_entry(&parent_entry, db, parent_abspath,
+ TRUE /* allow_unversioned */,
+ svn_node_dir,
+ FALSE /* need_parent_stub */,
+ pool, pool));
if (! parent_entry)
return svn_error_createf
(SVN_ERR_ENTRY_NOT_FOUND, NULL,
@@ -1431,9 +1517,15 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
svn_dirent_local_style(local_abspath, pool));
/* Init the modify flags. */
+ tmp_entry.schedule = svn_wc_schedule_add;
+ tmp_entry.kind = kind;
modify_flags = SVN_WC__ENTRY_MODIFY_SCHEDULE | SVN_WC__ENTRY_MODIFY_KIND;
+
if (! (is_replace || copyfrom_url))
- modify_flags |= SVN_WC__ENTRY_MODIFY_REVISION;
+ {
+ tmp_entry.revision = 0;
+ modify_flags |= SVN_WC__ENTRY_MODIFY_REVISION;
+ }
/* If a copy ancestor was given, make sure the copyfrom URL is in the same
repository (if possible) and put the proper ancestry info in the new
@@ -1461,10 +1553,6 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
modify_flags |= SVN_WC__ENTRY_MODIFY_CHECKSUM;
}
- tmp_entry.revision = 0;
- tmp_entry.kind = kind;
- tmp_entry.schedule = svn_wc_schedule_add;
-
/* Store the pristine properties to install them on working, because
we might delete the base table */
@@ -1479,13 +1567,17 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
pool, pool));
}
- /* Now, add the entry for this item to the parent_dir's
- entries file, marking it for addition. */
- SVN_ERR(svn_wc__entry_modify2(db, local_abspath, kind,
- kind == svn_node_dir /* parent_stub */,
- &tmp_entry, modify_flags, pool));
-
+ if (modify_flags)
+ {
+ if (kind == svn_node_dir)
+ SVN_ERR(svn_wc__entry_modify_stub(db, local_abspath,
+ &tmp_entry, modify_flags, pool));
+ else
+ SVN_ERR(svn_wc__entry_modify(db, local_abspath, kind,
+ &tmp_entry, modify_flags, pool));
+ }
+#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
/* If this is a replacement without history, we need to reset the
properties for PATH. */
/* ### this is totally bogus. we clear these cuz turds might have been
@@ -1495,6 +1587,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
&& copyfrom_url == NULL)
SVN_ERR(svn_wc__props_delete(db, local_abspath, svn_wc__props_working,
pool));
+#endif
if (is_replace)
{
@@ -1516,7 +1609,6 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
if (kind == svn_node_dir) /* scheduling a directory for addition */
{
-
if (! copyfrom_url)
{
const char *new_url;
@@ -1549,31 +1641,13 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
copyfrom_rev, depth, pool));
}
- /* The next block is to keep the access batons in sync. As long as we
- only have file locks inside access batons we have to open a new
- access baton for new directories here. svn_wc_add3() handles this
- case when we don't need the access batons for locking. */
- /* ### This block can be removed after we fully abandon access batons. */
+ /* ### This block can be removed after we centralise the db and have
+ ### infinite depth admin locks. */
if (! exists)
{
- svn_wc_adm_access_t *adm_access
- = svn_wc__adm_retrieve_internal2(db, parent_abspath, pool);
-
- if (adm_access != NULL)
- {
- const char *rel_path;
- apr_pool_t* adm_pool;
-
- SVN_ERR(svn_wc__temp_get_relpath(&rel_path, db, local_abspath,
- pool, pool));
-
- /* Open access baton for new child directory */
- adm_pool = svn_wc_adm_access_pool(adm_access);
- SVN_ERR(svn_wc_adm_open3(&adm_access, adm_access, rel_path,
- TRUE, copyfrom_url != NULL ? -1 : 0,
- cancel_func, cancel_baton,
- adm_pool));
- }
+ /* Lock on parent needs to be propogated into the child db. */
+ SVN_ERR(svn_wc__db_wclock_set(db, local_abspath, 0, pool));
+ SVN_ERR(svn_wc__db_temp_mark_locked(db, local_abspath, pool));
}
/* We're making the same mods we made above, but this time we'll
@@ -1583,15 +1657,18 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
This deletes the erroneous BASE_NODE for added directories and
adds a WORKING_NODE. */
- modify_flags |= SVN_WC__ENTRY_MODIFY_FORCE;
- modify_flags |= SVN_WC__ENTRY_MODIFY_INCOMPLETE;
- tmp_entry.schedule = is_replace
- ? svn_wc_schedule_replace
- : svn_wc_schedule_add;
- tmp_entry.incomplete = FALSE;
- SVN_ERR(svn_wc__entry_modify2(db, local_abspath, svn_node_dir,
- FALSE /* parent_stub */,
- &tmp_entry, modify_flags, pool));
+ if (modify_flags)
+ {
+ modify_flags |= SVN_WC__ENTRY_MODIFY_FORCE;
+ tmp_entry.schedule = (is_replace
+ ? svn_wc_schedule_replace
+ : svn_wc_schedule_add);
+ SVN_ERR(svn_wc__entry_modify(db, local_abspath, svn_node_dir,
+ &tmp_entry, modify_flags, pool));
+ }
+
+ SVN_ERR(svn_wc__db_temp_op_set_working_incomplete(
+ db, local_abspath, FALSE, pool));
if (copyfrom_url)
{
@@ -1610,20 +1687,18 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
const char *new_url =
svn_path_url_add_component2(parent_entry->url, base_name, pool);
- /* Change the entry urls recursively (but not the working rev). */
- SVN_ERR(svn_wc__do_update_cleanup(db, local_abspath,
- depth, new_url,
- parent_entry->repos,
- SVN_INVALID_REVNUM, NULL,
- NULL, FALSE, apr_hash_make(pool),
- pool));
+ /* ### copy.c will copy .svn subdirs, which means the whole
+ ### subtree is already "versioned". we now need to rejigger
+ ### the metadata to make it Proper for this location. */
/* Recursively add the 'copied' existence flag as well! */
SVN_ERR(mark_tree_copied(db, local_abspath,
exists ? status : svn_wc__db_status_added,
+ new_url,
pool));
/* Clean out the now-obsolete dav cache values. */
+ /* ### put this into above walk. clear all cached values. */
SVN_ERR(svn_wc__db_base_set_dav_cache(db, local_abspath, NULL,
pool));
}
@@ -1664,6 +1739,32 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_wc_register_file_external(svn_wc_context_t *wc_ctx,
+ const char *local_abspath,
+ const char *external_url,
+ const svn_opt_revision_t *external_peg_rev,
+ const svn_opt_revision_t *external_rev,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_t *db = wc_ctx->db;
+ const char *parent_abspath, *base_name, *repos_root_url;
+
+ svn_dirent_split(local_abspath, &parent_abspath, &base_name, scratch_pool);
+
+ SVN_ERR(svn_wc_add4(wc_ctx, local_abspath, svn_depth_infinity,
+ NULL, SVN_INVALID_REVNUM, NULL, NULL, NULL, NULL,
+ scratch_pool));
+ SVN_ERR(svn_wc__db_scan_base_repos(NULL, &repos_root_url, NULL, db,
+ parent_abspath, scratch_pool,
+ scratch_pool));
+ SVN_ERR(svn_wc__set_file_external_location(wc_ctx, local_abspath,
+ external_url, external_peg_rev,
+ external_rev, repos_root_url,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
/* Thoughts on Reversion.
@@ -1730,11 +1831,11 @@ revert_admin_things(svn_boolean_t *rever
}
-/* Revert PATH of on-disk KIND. ENTRY is the working copy entry for
- PATH. *DEPTH is the depth of the reversion crawl the caller is
+/* Revert LOCAL_ABSPATH in DB, where the on-disk node kind is DISK_KIND.
+ *DEPTH is the depth of the reversion crawl the caller is
using; this function may choose to override that value as needed.
- See svn_wc_revert3() for the interpretations of PARENT_ACCESS,
+ See svn_wc_revert4() for the interpretations of
USE_COMMIT_TIMES, CANCEL_FUNC and CANCEL_BATON.
Set *DID_REVERT to true if actually reverting anything, else do not
@@ -1826,18 +1927,6 @@ revert_entry(svn_depth_t *depth,
}
else if (kind == svn_wc__db_kind_dir)
{
- const char *path;
- SVN_ERR(svn_wc__temp_get_relpath(&path, db, local_abspath,
- pool, pool));
-
- /* We are trying to revert the current directory which is
- scheduled for addition. This is supposed to fail (Issue #854) */
- if (path[0] == '\0')
- return svn_error_create(SVN_ERR_WC_INVALID_OP_ON_CWD, NULL,
- _("Cannot revert addition of current "
- "directory; please try again from the "
- "parent directory"));
-
/* We don't need to check for excluded item, since we won't fall
into this code path in that case. */
@@ -1870,7 +1959,8 @@ revert_entry(svn_depth_t *depth,
adm_access, for which we definitely can't use the 'else'
code path (as it will remove the parent from version
control... (See issue 2425) */
- SVN_ERR(svn_wc__entry_remove(db, local_abspath, pool));
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
+ pool));
}
else
{
@@ -1908,6 +1998,7 @@ revert_entry(svn_depth_t *depth,
base_revision,
kind,
svn_wc__db_status_not_present,
+ NULL, NULL,
pool));
}
}
@@ -1955,11 +2046,8 @@ revert_internal(svn_wc__db_t *db,
svn_wc__db_kind_t db_kind;
svn_boolean_t unversioned;
const svn_wc_conflict_description2_t *tree_conflict;
- const char *path;
svn_error_t *err;
- SVN_ERR(svn_wc__temp_get_relpath(&path, db, local_abspath, pool, pool));
-
/* Check cancellation here, so recursive calls get checked early. */
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
@@ -1988,7 +2076,8 @@ revert_internal(svn_wc__db_t *db,
pool, pool));
if (unversioned && tree_conflict == NULL)
return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
- _("Cannot revert unversioned item '%s'"), path);
+ _("Cannot revert unversioned item '%s'"),
+ svn_dirent_local_style(local_abspath, pool));
/* Safeguard 1.5: is this a missing versioned directory? */
SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, pool));
@@ -2202,13 +2291,23 @@ svn_wc_get_pristine_copy_path(const char
{
svn_wc__db_t *db;
const char *local_abspath;
+ svn_error_t *err;
SVN_ERR(svn_wc__db_open(&db, svn_wc__db_openmode_readonly, NULL,
TRUE, TRUE, pool, pool));
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- SVN_ERR(svn_wc__text_base_path(pristine_path, db, local_abspath,
- FALSE, pool));
+ err = svn_wc__text_base_path_to_read(pristine_path, db, local_abspath,
+ pool, pool);
+ if (err && err->apr_err == SVN_ERR_WC_PATH_UNEXPECTED_STATUS)
+ {
+ const char *adm_abspath = svn_dirent_dirname(local_abspath, pool);
+
+ svn_error_clear(err);
+ *pristine_path = svn_wc__nonexistent_path(db, adm_abspath, pool);
+ return SVN_NO_ERROR;
+ }
+ SVN_ERR(err);
return svn_error_return(svn_wc__db_close(db));
}
@@ -2228,86 +2327,6 @@ svn_wc_get_pristine_contents2(svn_stream
}
svn_error_t *
-svn_wc__get_pristine_contents(svn_stream_t **contents,
- svn_wc__db_t *db,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_wc__db_status_t status;
- svn_wc__db_kind_t kind;
-
- SVN_ERR(svn_wc__db_read_info(&status, &kind,
- 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));
-
- /* Sanity */
- if (kind != svn_wc__db_kind_file)
- return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
- _("Can only get the pristine contents of files; "
- "'%s' is not a file"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
-
- if (status == svn_wc__db_status_added)
- {
- /* For an added node, we return "no stream". Make sure this is not
- copied-here or moved-here, in which case we return the copy/move
- source's contents. */
- SVN_ERR(svn_wc__db_scan_addition(&status,
- NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL,
- db, local_abspath,
- scratch_pool, scratch_pool));
- if (status == svn_wc__db_status_added)
- {
- /* Simply added. The pristine base does not exist. */
- *contents = NULL;
- return SVN_NO_ERROR;
- }
- }
- else if (status == svn_wc__db_status_not_present)
- /* We know that the delete of this node has been committed.
- This should be the same as if called on an unknown path. */
- return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
- _("Cannot get the pristine contents of '%s' "
- "because its delete is already committed"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
- else if (status == svn_wc__db_status_absent
- || status == svn_wc__db_status_excluded
- || status == svn_wc__db_status_incomplete)
- return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
- _("Cannot get the pristine contents of '%s' "
- "because it has an unexpected status"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
- else
- /* We know that it is a file, so we can't hit the _obstructed stati.
- Also, we should never see _base_deleted here. */
- SVN_ERR_ASSERT(status != svn_wc__db_status_obstructed
- && status != svn_wc__db_status_obstructed_add
- && status != svn_wc__db_status_obstructed_delete
- && status != svn_wc__db_status_base_deleted);
-
- /* ### TODO 1.7: use pristine store instead of this block: */
- {
- const char *text_base;
-
- SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath, FALSE,
- scratch_pool));
- SVN_ERR_ASSERT(text_base != NULL);
-
- return svn_error_return(svn_stream_open_readonly(contents, text_base,
- result_pool,
- scratch_pool));
- }
-}
-
-
-svn_error_t *
svn_wc__internal_remove_from_revision_control(svn_wc__db_t *db,
const char *local_abspath,
svn_boolean_t destroy_wf,
@@ -2343,7 +2362,11 @@ svn_wc__internal_remove_from_revision_co
svn_node_kind_t on_disk;
svn_boolean_t wc_special, local_special;
svn_boolean_t text_modified_p;
+#ifdef SVN_EXPERIMENTAL_PRISTINE
+ const svn_checksum_t *base_sha1_checksum, *working_sha1_checksum;
+#else
const char *text_base_file;
+#endif
/* Only check if the file was modified when it wasn't overwritten with a
special file */
@@ -2363,27 +2386,74 @@ svn_wc__internal_remove_from_revision_co
svn_dirent_local_style(local_abspath, scratch_pool));
}
+#ifdef SVN_EXPERIMENTAL_PRISTINE
+ /* Find the checksum(s) of the node's one or two pristine texts. Note
+ that read_info() may give us the one from WORKING_NODE again. */
+ err = svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ &base_sha1_checksum,
+ NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool);
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ base_sha1_checksum = NULL;
+ }
+ else
+ SVN_ERR(err);
+ err = svn_wc__db_read_info(NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ &working_sha1_checksum,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool);
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ working_sha1_checksum = NULL;
+ }
+ else
+ SVN_ERR(err);
+#else
SVN_ERR(svn_wc__text_base_path(&text_base_file, db, local_abspath,
- FALSE, scratch_pool));
-
- /* Clear the dav cache. */
- /* ### one day... (now?) this will simply be part of removing the
- ### BASE_NODE row. */
- SVN_ERR(svn_wc__db_base_set_dav_cache(db, local_abspath, NULL,
- scratch_pool));
+ scratch_pool));
+#endif
+#if (SVN_WC__VERSION < SVN_WC__PROPS_IN_DB)
/* Remove prop/NAME, prop-base/NAME.svn-base. */
SVN_ERR(svn_wc__props_delete(db, local_abspath, svn_wc__props_working,
scratch_pool));
SVN_ERR(svn_wc__props_delete(db, local_abspath, svn_wc__props_base,
scratch_pool));
+#endif
/* Remove NAME from PATH's entries file: */
- SVN_ERR(svn_wc__entry_remove(db, local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
+ scratch_pool));
/* Remove text-base/NAME.svn-base */
- SVN_ERR(svn_io_remove_file2(text_base_file,
- TRUE, scratch_pool));
+#ifdef SVN_EXPERIMENTAL_PRISTINE
+ /* Having removed the checksums that reference the pristine texts,
+ remove the pristine texts (if now totally unreferenced) from the
+ pristine store. Don't try to remove the same pristine text twice.
+ The two checksums might be the same, either because the copied base
+ was exactly the same as the replaced base, or just because the
+ ..._read_info() code above sets WORKING_SHA1_CHECKSUM to the base
+ checksum if there is no WORKING_NODE row. */
+ if (base_sha1_checksum)
+ SVN_ERR(svn_wc__db_pristine_remove(db, local_abspath,
+ base_sha1_checksum,
+ scratch_pool));
+ if (working_sha1_checksum
+ && ! svn_checksum_match(base_sha1_checksum, working_sha1_checksum))
+ SVN_ERR(svn_wc__db_pristine_remove(db, local_abspath,
+ working_sha1_checksum,
+ scratch_pool));
+#else
+ SVN_ERR(svn_io_remove_file2(text_base_file, TRUE, scratch_pool));
+#endif
/* If we were asked to destroy the working file, do so unless
it has local mods. */
@@ -2403,7 +2473,8 @@ svn_wc__internal_remove_from_revision_co
just delete the entry in the parent directory.
### This case disappears after we move to one DB. */
- SVN_ERR(svn_wc__entry_remove(db, local_abspath, scratch_pool));
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
+ scratch_pool));
}
else /* looking at THIS_DIR */
{
@@ -2413,10 +2484,6 @@ svn_wc__internal_remove_from_revision_co
/* ### sanity check: check 2 places for DELETED flag? */
- /* Get rid of the dav cache for this directory. */
- SVN_ERR(svn_wc__db_base_set_dav_cache(db, local_abspath, NULL,
- iterpool));
-
/* Walk over every entry. */
SVN_ERR(svn_wc__db_read_children(&children, db, local_abspath,
scratch_pool, iterpool));
@@ -2437,7 +2504,8 @@ svn_wc__internal_remove_from_revision_co
iterpool));
if (hidden)
{
- SVN_ERR(svn_wc__entry_remove(db, entry_abspath, iterpool));
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, entry_abspath,
+ iterpool));
continue;
}
@@ -2477,7 +2545,8 @@ svn_wc__internal_remove_from_revision_co
full_path. We need to remove that entry: */
if (! is_root)
{
- SVN_ERR(svn_wc__entry_remove(db, local_abspath, iterpool));
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
+ iterpool));
}
}
@@ -2699,28 +2768,33 @@ svn_wc__set_file_external_location(svn_w
const char *repos_root_url,
apr_pool_t *scratch_pool)
{
- svn_wc_entry_t entry = { 0 };
+ const char *external_repos_relpath;
+ const svn_opt_revision_t unspecified_rev = { svn_opt_revision_unspecified };
+
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+ SVN_ERR_ASSERT(!url || svn_uri_is_canonical(url, scratch_pool));
if (url)
{
- /* A repository root relative path is stored in the entry. */
- SVN_ERR_ASSERT(peg_rev);
- SVN_ERR_ASSERT(rev);
- entry.file_external_path = url + strlen(repos_root_url);
- entry.file_external_peg_rev = *peg_rev;
- entry.file_external_rev = *rev;
+ external_repos_relpath = svn_uri_is_child(repos_root_url, url, NULL);
+ SVN_ERR_ASSERT(external_repos_relpath != NULL);
+
+ external_repos_relpath = svn_path_uri_decode(external_repos_relpath,
+ scratch_pool);
+
+ SVN_ERR_ASSERT(peg_rev != NULL);
+ SVN_ERR_ASSERT(rev != NULL);
}
else
{
- entry.file_external_path = NULL;
- entry.file_external_peg_rev.kind = svn_opt_revision_unspecified;
- entry.file_external_rev.kind = svn_opt_revision_unspecified;
+ external_repos_relpath = NULL;
+ peg_rev = &unspecified_rev;
+ rev = &unspecified_rev;
}
- SVN_ERR(svn_wc__entry_modify2(wc_ctx->db, local_abspath,
- svn_node_unknown, FALSE,
- &entry, SVN_WC__ENTRY_MODIFY_FILE_EXTERNAL,
- scratch_pool));
+ SVN_ERR(svn_wc__db_temp_op_set_file_external(wc_ctx->db, local_abspath,
+ external_repos_relpath, peg_rev,
+ rev, scratch_pool));
return SVN_NO_ERROR;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.h?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.h Tue Aug 10 20:55:56 2010
@@ -64,10 +64,6 @@ extern "C" {
or replacement.) Likewise, if BASE_URL is non-null, then rewrite
all urls to be "telescoping" children of the base_url.
- If REMOVE_MISSING_DIRS is TRUE, then delete the entries for any
- missing directories. If NOTIFY_FUNC is non-null, invoke it with
- NOTIFY_BATON for each missing entry deleted.
-
EXCLUDE_PATHS is a hash containing const char * pathnames. Entries
for pathnames contained in EXCLUDE_PATHS are not touched by this
function. These pathnames should be absolute paths.
@@ -80,7 +76,6 @@ svn_error_t *svn_wc__do_update_cleanup(s
svn_revnum_t new_revision,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
- svn_boolean_t remove_missing_dirs,
apr_hash_t *exclude_paths,
apr_pool_t *pool);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/ambient_depth_filter_editor.c Tue Aug 10 20:55:56 2010
@@ -95,7 +95,6 @@ struct edit_baton
void *wrapped_edit_baton;
svn_wc__db_t *db;
const char *anchor_abspath;
- const char *anchor;
const char *target;
};
@@ -111,7 +110,7 @@ struct dir_baton
svn_boolean_t ambiently_excluded;
svn_depth_t ambient_depth;
struct edit_baton *edit_baton;
- const char *path;
+ const char *abspath;
void *wrapped_baton;
};
@@ -138,9 +137,9 @@ make_dir_baton(struct dir_baton **d_p,
/* Okay, no easy out, so allocate and initialize a dir baton. */
d = apr_pcalloc(pool, sizeof(*d));
- d->path = apr_pstrdup(pool, eb->anchor);
+ d->abspath = apr_pstrdup(pool, eb->anchor_abspath);
if (path)
- d->path = svn_dirent_join(d->path, path, pool);
+ d->abspath = svn_dirent_join(d->abspath, path, pool);
/* The svn_depth_unknown means that: 1) pb is the anchor; 2) there
is an non-null target, for which we are preparing the baton.
@@ -154,7 +153,8 @@ make_dir_baton(struct dir_baton **d_p,
svn_boolean_t exists = TRUE;
abspath = svn_dirent_join(eb->anchor_abspath,
- svn_dirent_skip_ancestor(eb->anchor, path),
+ svn_dirent_skip_ancestor(eb->anchor_abspath,
+ path),
pool);
err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -237,7 +237,8 @@ make_file_baton(struct file_baton **f_p,
const char *abspath;
abspath = svn_dirent_join(eb->anchor_abspath,
- svn_dirent_skip_ancestor(eb->anchor, path),
+ svn_dirent_skip_ancestor(eb->anchor_abspath,
+ path),
pool);
SVN_ERR(svn_wc__db_read_kind(&kind, pb->edit_baton->db, abspath, TRUE,
@@ -349,7 +350,8 @@ delete_entry(const char *path,
const char *abspath;
abspath = svn_dirent_join(eb->anchor_abspath,
- svn_dirent_skip_ancestor(eb->anchor, path),
+ svn_dirent_skip_ancestor(eb->anchor_abspath,
+ path),
pool);
SVN_ERR(svn_wc__db_read_kind(&kind, eb->db, abspath, TRUE, pool));
@@ -441,7 +443,8 @@ open_directory(const char *path,
this svn_wc_entry call. */
local_abspath = svn_dirent_join(eb->anchor_abspath,
- svn_dirent_skip_ancestor(eb->anchor, path),
+ svn_dirent_skip_ancestor(eb->anchor_abspath,
+ path),
pool);
@@ -644,7 +647,7 @@ svn_wc__ambient_depth_filter_editor(cons
void **edit_baton,
const svn_delta_editor_t *wrapped_editor,
void *wrapped_edit_baton,
- const char *anchor,
+ const char *anchor_abspath,
const char *target,
svn_wc__db_t *db,
apr_pool_t *pool)
@@ -652,6 +655,8 @@ svn_wc__ambient_depth_filter_editor(cons
svn_delta_editor_t *depth_filter_editor;
struct edit_baton *eb;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(anchor_abspath));
+
depth_filter_editor = svn_delta_default_editor(pool);
depth_filter_editor->set_target_revision = set_target_revision;
depth_filter_editor->open_root = open_root;
@@ -673,8 +678,7 @@ svn_wc__ambient_depth_filter_editor(cons
eb->wrapped_editor = wrapped_editor;
eb->wrapped_edit_baton = wrapped_edit_baton;
eb->db = db;
- SVN_ERR(svn_dirent_get_absolute(&eb->anchor_abspath, anchor, pool));
- eb->anchor = anchor;
+ eb->anchor_abspath = anchor_abspath;
eb->target = target;
*editor = depth_filter_editor;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c Tue Aug 10 20:55:56 2010
@@ -30,8 +30,6 @@
#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_hash.h>
-#include <apr_file_io.h>
-#include <apr_time.h>
#include <apr_errno.h>
#include "svn_types.h"
@@ -44,14 +42,13 @@
#include "svn_diff.h"
#include "wc.h"
-#include "log.h"
-#include "adm_ops.h"
-#include "props.h"
-#include "tree_conflicts.h"
-#include "workqueue.h"
+#include "wc_db.h"
+#include "conflicts.h"
-#include "svn_private_config.h"
#include "private/svn_wc_private.h"
+#include "private/svn_skel.h"
+
+#include "svn_private_config.h"
struct svn_wc_conflict_t
{
@@ -198,6 +195,69 @@ svn_wc_get_property_conflict_data(const
SVN_ERR_MALFUNCTION(); /* ### Not implemented yet */
}
+
+svn_skel_t *
+svn_wc__conflict_skel_new(apr_pool_t *result_pool)
+{
+ svn_skel_t *operation = svn_skel__make_empty_list(result_pool);
+ svn_skel_t *result = svn_skel__make_empty_list(result_pool);
+
+ svn_skel__prepend(operation, result);
+ return result;
+}
+
+
+static void
+prepend_prop_value(const svn_string_t *value,
+ svn_skel_t *skel,
+ apr_pool_t *result_pool)
+{
+ svn_skel_t *value_skel = svn_skel__make_empty_list(result_pool);
+
+ if (value != NULL)
+ {
+ const void *dup = apr_pmemdup(result_pool, value->data, value->len);
+
+ svn_skel__prepend(svn_skel__mem_atom(dup, value->len, result_pool),
+ value_skel);
+ }
+
+ svn_skel__prepend(value_skel, skel);
+}
+
+
+svn_error_t *
+svn_wc__conflict_skel_add_prop_conflict(
+ svn_skel_t *skel,
+ const char *prop_name,
+ const svn_string_t *original_value,
+ const svn_string_t *mine_value,
+ const svn_string_t *incoming_value,
+ const svn_string_t *incoming_base_value,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_skel_t *prop_skel = svn_skel__make_empty_list(result_pool);
+
+ /* ### check that OPERATION has been filled in. */
+
+ /* See notes/wc-ng/conflict-storage */
+ prepend_prop_value(incoming_base_value, prop_skel, result_pool);
+ prepend_prop_value(incoming_value, prop_skel, result_pool);
+ prepend_prop_value(mine_value, prop_skel, result_pool);
+ prepend_prop_value(original_value, prop_skel, result_pool);
+ svn_skel__prepend_str(apr_pstrdup(result_pool, prop_name), prop_skel,
+ result_pool);
+ svn_skel__prepend_str(SVN_WC__CONFLICT_KIND_PROP, prop_skel, result_pool);
+
+ /* Now we append PROP_SKEL to the end of the provided conflict SKEL. */
+ svn_skel__append(skel, prop_skel);
+
+ return SVN_NO_ERROR;
+}
+
+
+
/*** Resolving a conflict automatically ***/
@@ -269,9 +329,11 @@ resolve_conflict_on_node(svn_wc__db_t *d
const char *prop_reject_file = NULL;
svn_wc__db_kind_t kind;
int i;
- const apr_array_header_t *conflicts = NULL;
+ const apr_array_header_t *conflicts;
const char *conflict_dir_abspath;
+ *did_resolve = FALSE;
+
SVN_ERR(svn_wc__db_read_info(NULL, &kind, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -428,6 +490,24 @@ resolve_conflict_on_node(svn_wc__db_t *d
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_wc__resolve_text_conflict(svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool)
+{
+ svn_boolean_t ignored_result;
+
+ return svn_error_return(resolve_conflict_on_node(
+ db, local_abspath,
+ TRUE /* resolve_text */,
+ FALSE /* resolve_props */,
+ svn_wc_conflict_choose_merged,
+ &ignored_result,
+ scratch_pool));
+}
+
+
/* */
static svn_error_t *
resolve_one_conflict(svn_wc__db_t *db,
@@ -436,8 +516,6 @@ resolve_one_conflict(svn_wc__db_t *db,
const char *resolve_prop,
svn_boolean_t resolve_tree,
svn_wc_conflict_choice_t conflict_choice,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
apr_pool_t *scratch_pool)
@@ -459,9 +537,6 @@ resolve_one_conflict(svn_wc__db_t *db,
svn_pool_clear(iterpool);
- if (cancel_func)
- SVN_ERR(cancel_func(cancel_baton));
-
switch (cd->kind)
{
case svn_wc_conflict_kind_tree:
@@ -495,8 +570,8 @@ resolve_one_conflict(svn_wc__db_t *db,
SVN_ERR(resolve_conflict_on_node(db,
local_abspath,
- TRUE,
- FALSE,
+ TRUE /* resolve_text */,
+ FALSE /* resolve_props */,
conflict_choice,
&did_resolve,
iterpool));
@@ -509,6 +584,8 @@ resolve_one_conflict(svn_wc__db_t *db,
if (!resolve_prop)
break;
+ /* ### this is bogus. resolve_conflict_on_node() does not handle
+ ### individual property resolution. */
if (*resolve_prop != '\0' &&
strcmp(resolve_prop, cd->property_name) != 0)
{
@@ -519,8 +596,8 @@ resolve_one_conflict(svn_wc__db_t *db,
/* We don't have property name handling here yet :( */
SVN_ERR(resolve_conflict_on_node(db,
local_abspath,
- FALSE,
- TRUE,
+ FALSE /* resolve_text */,
+ TRUE /* resolve_props */,
conflict_choice,
&did_resolve,
iterpool));
@@ -597,7 +674,6 @@ recursive_resolve_conflict(svn_wc__db_t
resolve_prop,
resolve_tree,
conflict_choice,
- cancel_func, cancel_baton,
notify_func, notify_baton,
iterpool));
}
@@ -623,10 +699,9 @@ recursive_resolve_conflict(svn_wc__db_t
child_abspath = svn_dirent_join(local_abspath, name, iterpool);
- SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, TRUE, iterpool));
-
apr_hash_set(visited, name, APR_HASH_KEY_STRING, name);
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, TRUE, iterpool));
if (kind == svn_wc__db_kind_dir && depth < svn_depth_immediates)
continue;
@@ -663,12 +738,10 @@ recursive_resolve_conflict(svn_wc__db_t
child_abspath = svn_dirent_join(local_abspath, name, iterpool);
SVN_ERR(svn_wc__db_node_hidden(&hidden, db, child_abspath, iterpool));
-
if (hidden)
continue;
SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, TRUE, iterpool));
-
if (kind == svn_wc__db_kind_dir && depth < svn_depth_immediates)
continue;
@@ -689,39 +762,7 @@ recursive_resolve_conflict(svn_wc__db_t
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_wc__internal_resolved_conflict(svn_wc__db_t *db,
- const char *local_abspath,
- svn_depth_t depth,
- svn_boolean_t resolve_text,
- const char *resolve_prop,
- svn_boolean_t resolve_tree,
- svn_wc_conflict_choice_t conflict_choice,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- svn_wc_notify_func2_t notify_func,
- void *notify_baton,
- apr_pool_t *scratch_pool)
-{
- /* When the implementation still used the entry walker, depth
- unknown was translated to infinity. */
- if (depth == svn_depth_unknown)
- depth = svn_depth_infinity;
-
- return svn_error_return(
- recursive_resolve_conflict(db,
- local_abspath,
- depth,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- scratch_pool));
-}
-/* The public function */
svn_error_t *
svn_wc_resolved_conflict5(svn_wc_context_t *wc_ctx,
const char *local_abspath,
@@ -736,15 +777,27 @@ svn_wc_resolved_conflict5(svn_wc_context
void *notify_baton,
apr_pool_t *scratch_pool)
{
- return svn_error_return(
- svn_wc__internal_resolved_conflict(wc_ctx->db,
- local_abspath,
- depth,
- resolve_text,
- resolve_prop,
- resolve_tree,
- conflict_choice,
- cancel_func, cancel_baton,
- notify_func, notify_baton,
- scratch_pool));
+ /* ### the underlying code does NOT support resolving individual
+ ### properties. bail out if the caller tries it. */
+ if (resolve_prop != NULL && *resolve_prop != '\0')
+ return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+ U_("Resolving a single property is not (yet) "
+ "supported."));
+
+ /* When the implementation still used the entry walker, depth
+ unknown was translated to infinity. */
+ if (depth == svn_depth_unknown)
+ depth = svn_depth_infinity;
+
+ return svn_error_return(recursive_resolve_conflict(
+ wc_ctx->db,
+ local_abspath,
+ depth,
+ resolve_text,
+ resolve_prop,
+ resolve_tree,
+ conflict_choice,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ scratch_pool));
}