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 [22/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_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/adm_ops.c?rev=984153&r1=984152&r2=984153&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 18:06:17 2010
@@ -49,6 +49,7 @@
#include "svn_xml.h"
#include "svn_time.h"
#include "svn_diff.h"
+#include "svn_sorts.h"
#include "wc.h"
#include "log.h"
@@ -68,15 +69,17 @@
struct svn_wc_committed_queue_t
{
+ /* The pool in which ->queue is allocated. */
apr_pool_t *pool;
- apr_array_header_t *queue;
+ /* Mapping (const char *) local_abspath to (committed_queue_item_t *). */
+ apr_hash_t *queue;
+ /* Is any item in the queue marked as 'recursive'? */
svn_boolean_t have_recursive;
};
typedef struct
{
- const char *path;
- const char *adm_abspath;
+ const char *local_abspath;
svn_boolean_t recurse;
svn_boolean_t no_unlock;
svn_boolean_t keep_changelist;
@@ -85,6 +88,13 @@ typedef struct
} committed_queue_item_t;
+apr_pool_t *
+svn_wc__get_committed_queue_pool(const struct svn_wc_committed_queue_t *queue)
+{
+ return queue->pool;
+}
+
+
/*** Finishing updates and commits. ***/
@@ -237,34 +247,6 @@ tweak_entries(svn_wc__db_t *db,
return SVN_NO_ERROR;
}
-
-static svn_error_t *
-remove_revert_files(svn_wc__db_t *db,
- const char *adm_abspath,
- const char *local_abspath,
- apr_pool_t *pool)
-{
- svn_stringbuf_t *log_accum = svn_stringbuf_create("", pool);
- const char *revert_file;
- svn_node_kind_t kind;
-
- SVN_ERR(svn_wc__text_revert_path(&revert_file, db, local_abspath, pool));
-
- SVN_ERR(svn_io_check_path(revert_file, &kind, pool));
- if (kind == svn_node_file)
- SVN_ERR(svn_wc__loggy_remove(&log_accum, adm_abspath,
- revert_file, pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, adm_abspath, log_accum, pool);
-
- SVN_ERR(svn_wc__loggy_props_delete(&log_accum, db, local_abspath,
- adm_abspath,
- svn_wc__props_revert, pool));
-
- SVN_ERR(svn_wc__wq_add_loggy(db, adm_abspath, log_accum, pool));
-
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_wc__do_update_cleanup(svn_wc__db_t *db,
const char *local_abspath,
@@ -344,6 +326,7 @@ 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,
@@ -362,10 +345,11 @@ process_deletion_postcommit(svn_wc__db_t
}
+/* 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,
- const char *adm_abspath,
- const char *path,
+ const char *local_abspath,
svn_revnum_t new_revnum,
apr_time_t new_date,
const char *rev_author,
@@ -373,16 +357,15 @@ process_committed_leaf(svn_wc__db_t *db,
svn_boolean_t no_unlock,
svn_boolean_t keep_changelist,
const svn_checksum_t *checksum,
- const svn_wc_committed_queue_t *queue,
apr_pool_t *scratch_pool)
{
- const char *local_abspath;
svn_wc__db_status_t status;
svn_wc__db_kind_t kind;
const svn_checksum_t *copied_checksum;
+ const char *adm_abspath;
+ const char *tmp_text_base_abspath;
- SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL,
NULL, NULL, NULL,
@@ -394,6 +377,12 @@ process_committed_leaf(svn_wc__db_t *db,
db, local_abspath,
scratch_pool, scratch_pool));
+ if (kind == svn_wc__db_kind_dir)
+ adm_abspath = local_abspath;
+ else
+ adm_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+ SVN_ERR(svn_wc__write_check(db, adm_abspath, scratch_pool));
+
if (status == svn_wc__db_status_deleted
|| status == svn_wc__db_status_obstructed_delete)
{
@@ -409,64 +398,53 @@ process_committed_leaf(svn_wc__db_t *db,
/* 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(remove_revert_files(db, adm_abspath, local_abspath,
- scratch_pool));
+ SVN_ERR(svn_wc__wq_remove_revert_files(db, local_abspath, scratch_pool));
+ /* If we sent a delta (meaning: post-copy modification),
+ then this file will appear in the queue and so we should have
+ its checksum already. */
if (checksum == NULL)
{
- /* checksum will be NULL for recursive commits, which means that
- a directory was copied. When we recurse on that directory, the
- checksum will be NULL for all files. */
-
- /* If we sent a delta (meaning: post-copy modification),
- then this file will appear in the queue. See if we can
- find it. */
- int i;
-
- /* ### this is inefficient. switch to hash. that's round #2 */
-
- if (queue != NULL)
- for (i = 0; i < queue->queue->nelts; i++)
- {
- const committed_queue_item_t *cqi
- = APR_ARRAY_IDX(queue->queue, i,
- const committed_queue_item_t *);
- if (strcmp(path, cqi->path) == 0)
- {
- checksum = cqi->checksum;
- break;
- }
- }
- if (checksum == NULL)
+ /* It was copied and not modified. We should have a text
+ base for it. And the entry should have a checksum. */
+ if (copied_checksum != NULL)
{
- /* It was copied and not modified. We should have a text
- base for it. And the entry should have a checksum. */
- if (copied_checksum != NULL)
- {
- checksum = copied_checksum;
- }
+ checksum = copied_checksum;
+ }
#ifdef SVN_DEBUG
- else
- {
- /* If we copy a deleted file, then it will become scheduled
- for deletion, but there is no base text for it. So we
- cannot get/compute a checksum for this file. */
- SVN_ERR_ASSERT(
- status == svn_wc__db_status_deleted
- || status == svn_wc__db_status_obstructed_delete);
+ else
+ {
+ /* If we copy a deleted file, then it will become scheduled
+ for deletion, but there is no base text for it. So we
+ cannot get/compute a checksum for this file. */
+ SVN_ERR_ASSERT(
+ status == svn_wc__db_status_deleted
+ || status == svn_wc__db_status_obstructed_delete);
- /* checksum will remain NULL in this one case. */
- }
-#endif
+ /* checksum will remain NULL in this one case. */
}
+#endif
}
}
if (!no_unlock)
SVN_ERR(svn_wc__loggy_delete_lock(db, adm_abspath,
- path, scratch_pool));
+ local_abspath, scratch_pool));
- SVN_ERR(svn_wc__wq_add_postcommit(db, local_abspath, new_revnum,
+ /* Set TMP_TEXT_BASE_ABSPATH to the new text base to be installed, if any. */
+ {
+ 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_io_check_path(tmp_text_base_abspath, &new_base_kind,
+ scratch_pool));
+ if (new_base_kind != svn_node_file)
+ tmp_text_base_abspath = NULL;
+ }
+
+ SVN_ERR(svn_wc__wq_add_postcommit(db, local_abspath, tmp_text_base_abspath,
+ new_revnum,
new_date, rev_author, checksum,
new_dav_cache, keep_changelist,
scratch_pool));
@@ -475,35 +453,29 @@ process_committed_leaf(svn_wc__db_t *db,
}
-static svn_error_t *
-process_committed_internal(svn_wc__db_t *db,
- const char *adm_abspath,
- const char *path,
- svn_boolean_t recurse,
- svn_revnum_t new_revnum,
- apr_time_t new_date,
- const char *rev_author,
- apr_hash_t *new_dav_cache,
- svn_boolean_t no_unlock,
- svn_boolean_t keep_changelist,
- const svn_checksum_t *checksum,
- const svn_wc_committed_queue_t *queue,
- apr_pool_t *scratch_pool)
+svn_error_t *
+svn_wc__process_committed_internal(svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_boolean_t recurse,
+ svn_revnum_t new_revnum,
+ apr_time_t new_date,
+ const char *rev_author,
+ apr_hash_t *new_dav_cache,
+ svn_boolean_t no_unlock,
+ svn_boolean_t keep_changelist,
+ const svn_checksum_t *checksum,
+ const svn_wc_committed_queue_t *queue,
+ apr_pool_t *scratch_pool)
{
svn_wc__db_kind_t kind;
- const char *local_abspath;
-
- SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, scratch_pool));
- if (kind == svn_wc__db_kind_unknown)
- return SVN_NO_ERROR; /* deleted/absent. (?) ... nothing to do. */
- SVN_ERR(process_committed_leaf(db, adm_abspath, path,
+ SVN_ERR(process_committed_leaf(db, local_abspath,
new_revnum, new_date, rev_author,
new_dav_cache,
no_unlock, keep_changelist,
- checksum, queue, scratch_pool));
+ checksum, scratch_pool));
if (recurse && kind == svn_wc__db_kind_dir)
{
@@ -528,7 +500,6 @@ process_committed_internal(svn_wc__db_t
const char *name = APR_ARRAY_IDX(children, i, const char *);
const char *this_abspath;
svn_wc__db_status_t status;
- const char *this_path;
svn_pool_clear(iterpool);
@@ -550,22 +521,20 @@ process_committed_internal(svn_wc__db_t
if (status == svn_wc__db_status_excluded)
continue;
- /* Create child path by telescoping the main path. */
- this_path = svn_dirent_join(path, name, iterpool);
-
/* 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(process_committed_internal(db, this_abspath, this_path,
- TRUE /* recurse */,
- new_revnum, new_date,
- rev_author,
- NULL, TRUE /* no_unlock */,
- keep_changelist, NULL,
- queue, iterpool));
+ 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
@@ -586,12 +555,24 @@ process_committed_internal(svn_wc__db_t
if (replaced)
continue;
}
- SVN_ERR(process_committed_leaf(db, adm_abspath, this_path,
+
+ checksum = NULL;
+ if (queue != NULL)
+ {
+ const committed_queue_item_t *cqi
+ = apr_hash_get(queue->queue, this_abspath,
+ APR_HASH_KEY_STRING);
+
+ if (cqi != NULL)
+ checksum = cqi->checksum;
+ }
+
+ SVN_ERR(process_committed_leaf(db, this_abspath,
new_revnum,
new_date, rev_author, NULL,
TRUE /* no_unlock */,
keep_changelist,
- NULL, queue, iterpool));
+ checksum, iterpool));
}
}
@@ -602,28 +583,26 @@ process_committed_internal(svn_wc__db_t
}
-static apr_hash_t *
-convert_to_hash(const apr_array_header_t *wcprop_changes,
- apr_pool_t *result_pool)
+apr_hash_t *
+svn_wc__prop_array_to_hash(const apr_array_header_t *props,
+ apr_pool_t *result_pool)
{
int i;
- apr_hash_t *dav_cache;
+ apr_hash_t *prophash;
- if (wcprop_changes == NULL || wcprop_changes->nelts == 0)
+ if (props == NULL || props->nelts == 0)
return NULL;
- dav_cache = apr_hash_make(result_pool);
+ prophash = apr_hash_make(result_pool);
- for (i = 0; i < wcprop_changes->nelts; i++)
+ for (i = 0; i < props->nelts; i++)
{
- const svn_prop_t *prop = APR_ARRAY_IDX(wcprop_changes, i,
- const svn_prop_t *);
-
+ const svn_prop_t *prop = APR_ARRAY_IDX(props, i, const svn_prop_t *);
if (prop->value != NULL)
- apr_hash_set(dav_cache, prop->name, APR_HASH_KEY_STRING, prop->value);
+ apr_hash_set(prophash, prop->name, APR_HASH_KEY_STRING, prop->value);
}
- return dav_cache;
+ return prophash;
}
@@ -634,16 +613,15 @@ svn_wc_committed_queue_create(apr_pool_t
q = apr_palloc(pool, sizeof(*q));
q->pool = pool;
- q->queue = apr_array_make(pool, 1, sizeof(committed_queue_item_t *));
+ q->queue = apr_hash_make(pool);
q->have_recursive = FALSE;
return q;
}
svn_error_t *
-svn_wc_queue_committed2(svn_wc_committed_queue_t *queue,
- const char *path,
- svn_wc_adm_access_t *adm_access,
+svn_wc_queue_committed3(svn_wc_committed_queue_t *queue,
+ const char *local_abspath,
svn_boolean_t recurse,
const apr_array_header_t *wcprop_changes,
svn_boolean_t remove_lock,
@@ -653,6 +631,8 @@ svn_wc_queue_committed2(svn_wc_committed
{
committed_queue_item_t *cqi;
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
queue->have_recursive |= recurse;
/* Use the same pool as the one QUEUE was allocated in,
@@ -661,67 +641,41 @@ svn_wc_queue_committed2(svn_wc_committed
/* Add to the array with paths and options */
cqi = apr_palloc(queue->pool, sizeof(*cqi));
- cqi->path = path;
- cqi->adm_abspath = svn_wc__adm_access_abspath(adm_access);
+ cqi->local_abspath = local_abspath;
cqi->recurse = recurse;
cqi->no_unlock = !remove_lock;
cqi->keep_changelist = !remove_changelist;
cqi->checksum = checksum;
- cqi->new_dav_cache = convert_to_hash(wcprop_changes, queue->pool);
+ cqi->new_dav_cache = svn_wc__prop_array_to_hash(wcprop_changes, queue->pool);
- APR_ARRAY_PUSH(queue->queue, committed_queue_item_t *) = cqi;
+ apr_hash_set(queue->queue, local_abspath, APR_HASH_KEY_STRING, cqi);
return SVN_NO_ERROR;
}
-
-/* NOTE: this function doesn't move to deprecated.c because of its need
- for the internals of svn_wc_committed_queue_t. */
-svn_error_t *
-svn_wc_queue_committed(svn_wc_committed_queue_t **queue,
- const char *path,
- svn_wc_adm_access_t *adm_access,
- svn_boolean_t recurse,
- const apr_array_header_t *wcprop_changes,
- svn_boolean_t remove_lock,
- svn_boolean_t remove_changelist,
- const unsigned char *digest,
- apr_pool_t *pool)
-{
- const svn_checksum_t *checksum;
-
- if (digest)
- checksum = svn_checksum__from_digest(digest, svn_checksum_md5,
- (*queue)->pool);
- else
- checksum = NULL;
-
- return svn_wc_queue_committed2(*queue, path, adm_access, recurse,
- wcprop_changes, remove_lock,
- remove_changelist,
- checksum, pool);
-}
-
-
/* Return TRUE if any item of QUEUE is a parent of ITEM and will be
processed recursively, return FALSE otherwise.
+
+ The algorithmic complexity of this search implementation is O(queue
+ length), but it's quite quick.
*/
static svn_boolean_t
-have_recursive_parent(apr_array_header_t *queue, int item)
+have_recursive_parent(apr_hash_t *queue,
+ const committed_queue_item_t *item,
+ apr_pool_t *scratch_pool)
{
- int i;
- const char *path
- = APR_ARRAY_IDX(queue, item, committed_queue_item_t *)->path;
+ apr_hash_index_t *hi;
+ const char *local_abspath = item->local_abspath;
- for (i = 0; i < queue->nelts; i++)
+ for (hi = apr_hash_first(scratch_pool, queue); hi; hi = apr_hash_next(hi))
{
- const committed_queue_item_t *qi;
+ const committed_queue_item_t *qi = svn__apr_hash_index_val(hi);
- if (i == item)
+ if (qi == item)
continue;
- qi = APR_ARRAY_IDX(queue, i, const committed_queue_item_t *);
- if (qi->recurse && svn_dirent_is_child(qi->path, path, NULL))
+ if (qi->recurse && svn_dirent_is_child(qi->local_abspath, local_abspath,
+ NULL))
return TRUE;
}
@@ -729,114 +683,75 @@ have_recursive_parent(apr_array_header_t
}
svn_error_t *
-svn_wc_process_committed_queue(svn_wc_committed_queue_t *queue,
- svn_wc_adm_access_t *adm_access,
- svn_revnum_t new_revnum,
- const char *rev_date,
- const char *rev_author,
- apr_pool_t *pool)
+svn_wc_process_committed_queue2(svn_wc_committed_queue_t *queue,
+ svn_wc_context_t *wc_ctx,
+ svn_revnum_t new_revnum,
+ const char *rev_date,
+ const char *rev_author,
+ apr_pool_t *scratch_pool)
{
- svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
+ apr_array_header_t *sorted_queue;
int i;
- apr_pool_t *iterpool = svn_pool_create(pool);
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
apr_time_t new_date;
if (rev_date)
- SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool));
+ SVN_ERR(svn_time_from_cstring(&new_date, rev_date, scratch_pool));
else
new_date = 0;
- for (i = 0; i < queue->queue->nelts; i++)
- {
- const committed_queue_item_t *cqi
- = APR_ARRAY_IDX(queue->queue, i, const committed_queue_item_t *);
+ /* Process the queued items in order of their paths. (The requirement is
+ * probably just that a directory must be processed before its children.) */
+ sorted_queue = svn_sort__hash(queue->queue, svn_sort_compare_items_as_paths,
+ scratch_pool);
+ for (i = 0; i < sorted_queue->nelts; i++)
+ {
+ const svn_sort__item_t *sort_item
+ = &APR_ARRAY_IDX(sorted_queue, i, svn_sort__item_t);
+ const committed_queue_item_t *cqi = sort_item->value;
svn_pool_clear(iterpool);
- /* If there are some recursive items, then see if this item is a
- child of one, and will (implicitly) be accounted for. */
- if (queue->have_recursive && have_recursive_parent(queue->queue, i))
+ /* Skip this item if it is a child of a recursive item, because it has
+ been (or will be) accounted for when that recursive item was (or
+ will be) processed. */
+ if (queue->have_recursive && have_recursive_parent(queue->queue, cqi,
+ iterpool))
continue;
- SVN_ERR(process_committed_internal(db, cqi->adm_abspath, cqi->path,
- cqi->recurse,
- new_revnum, new_date, rev_author,
- cqi->new_dav_cache,
- cqi->no_unlock,
- cqi->keep_changelist,
- cqi->checksum, queue, iterpool));
+ SVN_ERR(svn_wc__process_committed_internal(wc_ctx->db, cqi->local_abspath,
+ cqi->recurse, new_revnum,
+ new_date, rev_author,
+ cqi->new_dav_cache,
+ cqi->no_unlock,
+ cqi->keep_changelist,
+ cqi->checksum, queue,
+ iterpool));
- SVN_ERR(svn_wc__wq_run(db, cqi->adm_abspath, NULL, NULL, iterpool));
+ SVN_ERR(svn_wc__wq_run(wc_ctx->db, cqi->local_abspath, NULL, NULL,
+ iterpool));
}
- queue->queue->nelts = 0;
+ svn_hash__clear(queue->queue, scratch_pool);
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-svn_error_t *
-svn_wc_process_committed4(const char *path,
- svn_wc_adm_access_t *adm_access,
- svn_boolean_t recurse,
- svn_revnum_t new_revnum,
- const char *rev_date,
- const char *rev_author,
- const apr_array_header_t *wcprop_changes,
- svn_boolean_t remove_lock,
- svn_boolean_t remove_changelist,
- const unsigned char *digest,
- apr_pool_t *pool)
-{
- svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
- const char *adm_abspath = svn_wc__adm_access_abspath(adm_access);
- const svn_checksum_t *checksum;
- apr_time_t new_date;
-
- if (rev_date)
- SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool));
- else
- new_date = 0;
-
- if (digest)
- checksum = svn_checksum__from_digest(digest, svn_checksum_md5, pool);
- else
- checksum = NULL;
-
- SVN_ERR(process_committed_internal(db, adm_abspath,
- path, recurse,
- new_revnum, new_date, rev_author,
- convert_to_hash(wcprop_changes, pool),
- !remove_lock,!remove_changelist,
- checksum, NULL,
- pool));
-
- /* Run the log file(s) we just created. */
- return svn_error_return(svn_wc__wq_run(db, adm_abspath, NULL, NULL, pool));
-}
-
-
-/* Recursively mark a tree LOCAL_ABSPATH with SCHEDULE svn_wc_schedule_delete
+/* Recursively mark a tree DIR_ABSPATH with schedule svn_wc_schedule_delete
and a KEEP_LOCAL flag. */
-/* ### If the implementation looks familiar to mark_tree_copied(), that is not
- strictly coincidence. The function was duplicated, to make it easier to
- replace these two specific cases for WC-NG. */
static svn_error_t *
mark_tree_deleted(svn_wc__db_t *db,
const char *dir_abspath,
svn_boolean_t keep_local,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
apr_pool_t *pool)
{
apr_pool_t *iterpool = svn_pool_create(pool);
const apr_array_header_t *children;
- const svn_wc_entry_t *entry;
- svn_wc_entry_t tmp_entry;
int i;
/* Read the entries file for this directory. */
@@ -848,6 +763,7 @@ mark_tree_deleted(svn_wc__db_t *db,
const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
const char *child_abspath;
svn_boolean_t hidden;
+ svn_wc__db_kind_t kind;
/* Clear our per-iteration pool. */
svn_pool_clear(iterpool);
@@ -859,36 +775,19 @@ mark_tree_deleted(svn_wc__db_t *db,
if (hidden)
continue;
- SVN_ERR(svn_wc__get_entry(&entry, db, child_abspath, FALSE,
- svn_node_unknown, FALSE, iterpool, iterpool));
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, child_abspath, FALSE, iterpool));
- /* If this is a directory, recurse. */
- if (entry->kind == svn_node_dir)
+ /* If this is a directory, recurse; otherwise, delete. */
+ if (kind == svn_wc__db_kind_dir)
{
SVN_ERR(mark_tree_deleted(db, child_abspath,
keep_local,
- cancel_func, cancel_baton,
notify_func, notify_baton,
iterpool));
}
-
- /* If this node has no function after the delete, remove it
- directly. Otherwise svn_wc__entry_modify2 would do this for us,
- but using the entries api would leave the db handle open */
- /* ### BH: This check matches the only case in fold_scheduling()
- that removes the entry via delete scheduling */
- if (entry->schedule == svn_wc_schedule_add && !entry->deleted)
- {
- SVN_ERR(svn_wc__entry_remove(db, child_abspath, pool));
- SVN_ERR(svn_wc__db_temp_forget_directory(db, dir_abspath, pool));
- }
else
{
- tmp_entry.schedule = svn_wc_schedule_delete;
- SVN_ERR(svn_wc__entry_modify2(db, child_abspath, svn_node_unknown,
- TRUE, &tmp_entry,
- SVN_WC__ENTRY_MODIFY_SCHEDULE,
- iterpool));
+ SVN_ERR(svn_wc__db_temp_op_delete(db, child_abspath, pool));
}
/* Tell someone what we've done. */
@@ -900,26 +799,10 @@ mark_tree_deleted(svn_wc__db_t *db,
iterpool);
}
- /* Handle "this dir" for states that need it done post-recursion. */
- SVN_ERR(svn_wc__get_entry(&entry, db, dir_abspath, FALSE,
- svn_node_dir, FALSE, iterpool, iterpool));
-
- /* Uncommitted directories (schedule add) that are to be scheduled for
- deletion are a special case, they don't need to be changed as they
- will be removed from their parent's entry list.
- The files and directories are left on the disk in this special
- case, so KEEP_LOCAL doesn't need to be set either. */
- if (entry->schedule != svn_wc_schedule_add)
- {
- tmp_entry.schedule = svn_wc_schedule_delete;
- tmp_entry.keep_local = keep_local;
-
- SVN_ERR(svn_wc__entry_modify2(db, dir_abspath, svn_node_dir, FALSE,
- &tmp_entry,
- SVN_WC__ENTRY_MODIFY_SCHEDULE |
- SVN_WC__ENTRY_MODIFY_KEEP_LOCAL,
- iterpool));
- }
+ /* Handle directories now, after handling their kiddos. */
+ SVN_ERR(svn_wc__db_temp_op_delete(db, dir_abspath, iterpool));
+ if (keep_local)
+ SVN_ERR(svn_wc__db_temp_set_keep_local(db, dir_abspath, TRUE, iterpool));
/* Destroy our per-iteration pool. */
svn_pool_destroy(iterpool);
@@ -1082,7 +965,7 @@ erase_from_wc(svn_wc__db_t *db,
hi;
hi = apr_hash_next(hi))
{
- const char *name = svn_apr_hash_index_key(hi);
+ const char *name = svn__apr_hash_index_key(hi);
svn_pool_clear(iterpool);
@@ -1123,7 +1006,6 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
svn_boolean_t was_copied = FALSE;
svn_boolean_t was_deleted = FALSE; /* Silence a gcc uninitialized warning */
svn_error_t *err;
- const char *parent_abspath = svn_dirent_dirname(local_abspath, pool);
svn_wc__db_status_t status;
svn_wc__db_kind_t kind;
svn_boolean_t base_shadowed;
@@ -1214,7 +1096,6 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
SVN_ERR(mark_tree_deleted(wc_ctx->db,
local_abspath,
keep_local,
- cancel_func, cancel_baton,
notify_func, notify_baton,
pool));
}
@@ -1229,63 +1110,20 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
if (kind != svn_wc__db_kind_dir || !was_add || was_deleted)
{
- /* We need to mark this entry for deletion in its parent's entries
- file, so we split off base_name from the parent path, then fold in
- the addition of a delete flag. */
- svn_stringbuf_t *log_accum = svn_stringbuf_create("", pool);
- svn_wc_entry_t tmp_entry;
-
- /* Edit the entry to reflect the now deleted state.
- entries.c:fold_entry() clears the values of copied, copyfrom_rev
- and copyfrom_url. */
- tmp_entry.schedule = svn_wc_schedule_delete;
- SVN_ERR(svn_wc__loggy_entry_modify(&log_accum,
- parent_abspath,
- local_abspath, &tmp_entry,
- SVN_WC__ENTRY_MODIFY_SCHEDULE,
- pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
-
- /* is it a replacement with history? */
- if (was_replace && was_copied)
- {
- const char *text_base, *text_revert;
-
- SVN_ERR(svn_wc__text_base_path(&text_base, wc_ctx->db, local_abspath,
- FALSE, pool));
-
- SVN_ERR(svn_wc__text_revert_path(&text_revert, wc_ctx->db,
- local_abspath, pool));
-
- if (kind != svn_wc__db_kind_dir) /* Dirs don't have text-bases */
- /* Restore the original text-base */
- SVN_ERR(svn_wc__loggy_move(&log_accum,
- parent_abspath,
- text_revert, text_base,
- pool, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
-
- SVN_ERR(svn_wc__loggy_revert_props_restore(&log_accum, wc_ctx->db,
- local_abspath,
- parent_abspath, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
- }
- if (was_add)
- {
- SVN_ERR(svn_wc__loggy_props_delete(&log_accum, wc_ctx->db,
- local_abspath, parent_abspath,
- svn_wc__props_base, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
+ const char *parent_abspath = svn_dirent_dirname(local_abspath, pool);
- SVN_ERR(svn_wc__loggy_props_delete(&log_accum, wc_ctx->db,
- local_abspath, parent_abspath,
- svn_wc__props_working, pool));
- SVN_WC__FLUSH_LOG_ACCUM(db, parent_abspath, log_accum, pool);
- }
-
- SVN_ERR(svn_wc__wq_add_loggy(db, parent_abspath, log_accum, pool));
+ /* ### The following two operations should be inside one SqLite
+ transaction. For even better behavior the tree operation
+ before this block needs the same handling.
+ Luckily most of this is for free once properties and pristine
+ are handled in the WC-NG way. */
+ SVN_ERR(svn_wc__db_temp_op_delete(wc_ctx->db, local_abspath, pool));
+ SVN_ERR(svn_wc__wq_add_delete(wc_ctx->db, parent_abspath, local_abspath,
+ kind, was_add, was_copied, was_replace,
+ pool));
- SVN_ERR(svn_wc__run_log2(db, parent_abspath, pool));
+ SVN_ERR(svn_wc__wq_run(db, parent_abspath, cancel_func, cancel_baton,
+ pool));
}
/* Report the deletion to the caller. */
@@ -1362,22 +1200,44 @@ svn_wc_get_ancestry2(const char **url,
result_pool, scratch_pool));
}
-/* Recursively mark a tree LOCAL_ABSPATH with a COPIED flag, skip items
- scheduled for deletion. */
-/* ### If the implementation looks familiar to mark_tree_deleted(), that
- is not strictly coincidence. The function was duplicated, to make it
- easier to replace these two specific cases for WC-NG. */
+/* 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 *
+mark_item_copied(svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_wc__db_kind_t local_kind,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *props;
+ svn_wc_entry_t tmp_entry;
+ svn_node_kind_t kind =
+ local_kind == svn_wc__db_kind_dir ? svn_node_dir : svn_node_unknown;
+
+ /* Squirrel away the pristine properties to install them on
+ working, because we might delete the base table */
+ 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));
+
+ /* Reinstall the pristine properties on WORKING */
+ SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath, props,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Recursively mark a tree DIR_ABSPATH (whose status is DIR_STATUS)
+ with a COPIED flag, skip items scheduled for deletion. */
static svn_error_t *
mark_tree_copied(svn_wc__db_t *db,
const char *dir_abspath,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
+ svn_wc__db_status_t dir_status,
apr_pool_t *pool)
{
apr_pool_t *iterpool = svn_pool_create(pool);
const apr_array_header_t *children;
- const svn_wc_entry_t *entry;
- svn_wc_entry_t tmp_entry;
int i;
/* Read the entries file for this directory. */
@@ -1388,7 +1248,8 @@ mark_tree_copied(svn_wc__db_t *db,
{
const char *child_basename = APR_ARRAY_IDX(children, i, const char *);
const char *child_abspath;
- apr_hash_t *props;
+ svn_wc__db_status_t child_status;
+ svn_wc__db_kind_t child_kind;
svn_boolean_t hidden;
/* Clear our per-iteration pool. */
@@ -1401,64 +1262,38 @@ mark_tree_copied(svn_wc__db_t *db,
if (hidden)
continue;
- SVN_ERR(svn_wc__get_entry(&entry, db, child_abspath, FALSE,
- svn_node_unknown, FALSE, iterpool, iterpool));
+ SVN_ERR(svn_wc__db_read_info(&child_status, &child_kind, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ db, child_abspath, iterpool, iterpool));
/* Skip deleted items. */
- if (entry->schedule == svn_wc_schedule_delete)
+ if ((child_status == svn_wc__db_status_deleted) ||
+ (child_status == svn_wc__db_status_obstructed_delete))
continue;
- /* If this is a directory, recurse. */
- if (entry->kind == svn_node_dir)
+ /* 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,
- cancel_func, cancel_baton,
- iterpool));
+ SVN_ERR(mark_tree_copied(db, child_abspath, child_status, iterpool));
+ }
+ else
+ {
+ SVN_ERR(mark_item_copied(db, child_abspath, child_kind, iterpool));
}
-
- /* Store the pristine properties to install them on working, because
- we might delete the base table */
- if (entry->kind != svn_node_dir)
- SVN_ERR(svn_wc__db_read_pristine_props(&props, db, child_abspath,
- iterpool, iterpool));
- tmp_entry.copied = TRUE;
- SVN_ERR(svn_wc__entry_modify2(db, child_abspath, svn_node_unknown,
- TRUE, &tmp_entry,
- SVN_WC__ENTRY_MODIFY_COPIED,
- iterpool));
-
- /* Reinstall the pristine properties on working */
- if (entry->kind != svn_node_dir)
- SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, child_abspath, props,
- TRUE, iterpool));
/* Remove now obsolete dav cache values. */
SVN_ERR(svn_wc__db_base_set_dav_cache(db, child_abspath, NULL,
iterpool));
}
- /* Handle "this dir" for states that need it done post-recursion. */
- SVN_ERR(svn_wc__get_entry(&entry, db, dir_abspath, FALSE,
- svn_node_dir, FALSE, iterpool, iterpool));
-
- /* If setting the COPIED flag, skip deleted items. */
- if (entry->schedule != svn_wc_schedule_delete)
+ /* Here's where we handle directories. */
+ if (!((dir_status == svn_wc__db_status_deleted) ||
+ (dir_status == svn_wc__db_status_obstructed_delete)))
{
- apr_hash_t *props;
- tmp_entry.copied = TRUE;
-
- /* Store the pristine properties to install them on working, because
- we might delete the base table */
- SVN_ERR(svn_wc__db_read_pristine_props(&props, db, dir_abspath,
- iterpool, iterpool));
-
- SVN_ERR(svn_wc__entry_modify2(db, dir_abspath, svn_node_dir, FALSE,
- &tmp_entry, SVN_WC__ENTRY_MODIFY_COPIED,
- iterpool));
-
- /* Reinstall the pristine properties on working */
- SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, dir_abspath, props,
- TRUE, iterpool));
+ SVN_ERR(mark_item_copied(db, dir_abspath, svn_wc__db_kind_dir,
+ iterpool));
}
/* Destroy our per-iteration pool. */
@@ -1635,8 +1470,14 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
we might delete the base table */
if ((exists && status != svn_wc__db_status_not_present)
&& !is_replace && copyfrom_url != NULL)
- SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
- pool, pool));
+ {
+ /* NOTE: the conditions to reach here *exactly* match the
+ conditions used below when PROPS is referenced.
+ Be careful to keep these sets of conditionals aligned to avoid
+ an uninitialized PROPS value. */
+ SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
+ pool, pool));
+ }
/* Now, add the entry for this item to the parent_dir's
entries file, marking it for addition. */
@@ -1685,7 +1526,11 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
pool);
/* Make sure this new directory has an admistrative subdirectory
- created inside of it */
+ created inside of it.
+
+ This creates a BASE_NODE for an added directory, really
+ it should create a WORKING_NODE. It gets removed by the
+ next modify2 call. */
SVN_ERR(svn_wc__internal_ensure_adm(db, local_abspath,
new_url, parent_entry->repos,
parent_entry->uuid, 0,
@@ -1734,7 +1579,10 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
/* We're making the same mods we made above, but this time we'll
force the scheduling. Also make sure to undo the
'incomplete' flag which svn_wc__internal_ensure_adm() sets by
- default. */
+ default.
+
+ 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
@@ -1772,7 +1620,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
/* Recursively add the 'copied' existence flag as well! */
SVN_ERR(mark_tree_copied(db, local_abspath,
- cancel_func, cancel_baton,
+ exists ? status : svn_wc__db_status_added,
pool));
/* Clean out the now-obsolete dav cache values. */
@@ -1787,12 +1635,20 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
if (exists && status != svn_wc__db_status_not_present)
{
if (!is_replace && copyfrom_url != NULL)
- SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, local_abspath, props,
- TRUE, pool));
+ {
+ /* NOTE: the conditions to reach here *exactly* match the
+ conditions that were used to initialize the PROPS localvar.
+ Be careful to keep these sets of conditionals aligned to avoid
+ an uninitialized PROPS value. */
+ SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath, props,
+ pool));
+ }
else
- SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, local_abspath,
- apr_hash_make(pool),
- TRUE, pool));
+ {
+ SVN_ERR(svn_wc__db_temp_working_set_props(db, local_abspath,
+ apr_hash_make(pool),
+ pool));
+ }
}
/* Report the addition to the caller. */
@@ -1858,6 +1714,7 @@ svn_wc_add4(svn_wc_context_t *wc_ctx,
*/
+/* */
static svn_error_t *
revert_admin_things(svn_boolean_t *reverted,
svn_wc__db_t *db,
@@ -1889,21 +1746,35 @@ static svn_error_t *
revert_entry(svn_depth_t *depth,
svn_wc__db_t *db,
const char *local_abspath,
- svn_node_kind_t kind,
- const svn_wc_entry_t *entry,
+ svn_node_kind_t disk_kind,
svn_boolean_t use_commit_times,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_boolean_t *did_revert,
apr_pool_t *pool)
{
+ svn_wc__db_status_t status;
+ svn_wc__db_kind_t kind;
+ svn_boolean_t replaced;
+
/* Initialize this even though revert_admin_things() is guaranteed
to set it, because we don't know that revert_admin_things() will
be called. */
svn_boolean_t reverted = FALSE;
+ 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, pool, pool));
+
+ SVN_ERR(svn_wc__internal_is_replaced(&replaced, db, local_abspath, pool));
+
/* Additions. */
- if (entry->schedule == svn_wc_schedule_add)
+ if ((status == svn_wc__db_status_added
+ || status == svn_wc__db_status_obstructed_add)
+ && !replaced)
{
svn_revnum_t base_revision;
const char *repos_relpath;
@@ -1925,9 +1796,9 @@ revert_entry(svn_depth_t *depth,
### shoved back into the database. this is why we need to record
### the repository information, and the BASE revision. */
- if (entry->kind == svn_node_file)
+ if (kind == svn_wc__db_kind_file)
{
- was_deleted = entry->deleted;
+ was_deleted = (status == svn_wc__db_status_not_present);
if (was_deleted)
{
/* Remember the BASE revision. */
@@ -1953,7 +1824,7 @@ revert_entry(svn_depth_t *depth,
cancel_baton,
pool));
}
- else if (entry->kind == svn_node_dir)
+ else if (kind == svn_wc__db_kind_dir)
{
const char *path;
SVN_ERR(svn_wc__temp_get_relpath(&path, db, local_abspath,
@@ -1990,7 +1861,7 @@ revert_entry(svn_depth_t *depth,
pool, pool));
}
- if (kind == svn_node_none
+ if (disk_kind == svn_node_none
|| svn_wc__adm_missing(db, local_abspath, pool))
{
/* Schedule add but missing, just remove the entry
@@ -2035,26 +1906,23 @@ revert_entry(svn_depth_t *depth,
db, local_abspath,
repos_relpath, repos_root_url, repos_uuid,
base_revision,
- entry->kind == svn_node_dir
- ? svn_wc__db_kind_dir
- : svn_wc__db_kind_file,
+ kind,
svn_wc__db_status_not_present,
pool));
}
}
/* Regular prop and text edit. */
/* Deletions and replacements. */
- else if (entry->schedule == svn_wc_schedule_normal
- || entry->schedule == svn_wc_schedule_delete
- || entry->schedule == svn_wc_schedule_replace)
+ else if (status == svn_wc__db_status_normal
+ || status == svn_wc__db_status_deleted
+ || replaced)
{
/* Revert the prop and text mods (if any). */
SVN_ERR(revert_admin_things(&reverted, db, local_abspath,
use_commit_times, pool));
/* Force recursion on replaced directories. */
- if (entry->kind == svn_node_dir
- && entry->schedule == svn_wc_schedule_replace)
+ if (kind == svn_wc__db_kind_dir && replaced)
*depth = svn_depth_infinity;
}
@@ -2082,8 +1950,10 @@ revert_internal(svn_wc__db_t *db,
void *notify_baton,
apr_pool_t *pool)
{
- svn_node_kind_t kind;
- const svn_wc_entry_t *entry;
+ svn_node_kind_t disk_kind;
+ svn_wc__db_status_t status;
+ 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;
@@ -2097,25 +1967,36 @@ revert_internal(svn_wc__db_t *db,
/* Safeguard 1: the item must be versioned for any reversion to make sense,
except that a tree conflict can exist on an unversioned item. */
- err = svn_wc__get_entry(&entry, db, local_abspath, TRUE, svn_node_unknown,
- FALSE, pool, pool);
+ 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,
+ NULL,
+ db, local_abspath, pool, pool);
- if (err && err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND)
- svn_error_clear(err);
+ if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ {
+ svn_error_clear(err);
+ unversioned = TRUE;
+ }
+ else if (err)
+ return svn_error_return(err);
else
- SVN_ERR(err);
+ unversioned = FALSE;
SVN_ERR(svn_wc__db_op_read_tree_conflict(&tree_conflict, db, local_abspath,
pool, pool));
- if (entry == NULL && tree_conflict == NULL)
+ if (unversioned && tree_conflict == NULL)
return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
_("Cannot revert unversioned item '%s'"), path);
/* Safeguard 1.5: is this a missing versioned directory? */
- SVN_ERR(svn_io_check_path(local_abspath, &kind, pool));
- if (entry && (entry->kind == svn_node_dir))
+ SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, pool));
+ if (!unversioned && (db_kind == svn_wc__db_kind_dir))
{
- if ((kind != svn_node_dir) && (entry->schedule != svn_wc_schedule_add))
+ if ((disk_kind != svn_node_dir)
+ && (status != svn_wc__db_status_added)
+ && (status != svn_wc__db_status_obstructed_add))
{
/* When the directory itself is missing, we can't revert without
hitting the network. Someday a '--force' option will
@@ -2133,7 +2014,8 @@ revert_internal(svn_wc__db_t *db,
}
/* Safeguard 2: can we handle this entry's recorded kind? */
- if (entry && (entry->kind != svn_node_file) && (entry->kind != svn_node_dir))
+ if (!unversioned
+ && (db_kind != svn_wc__db_kind_file) && (db_kind != svn_wc__db_kind_dir))
return svn_error_createf
(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
_("Cannot revert '%s': unsupported entry node kind"),
@@ -2141,9 +2023,9 @@ revert_internal(svn_wc__db_t *db,
/* Safeguard 3: can we deal with the node kind of PATH currently in
the working copy? */
- if ((kind != svn_node_none)
- && (kind != svn_node_file)
- && (kind != svn_node_dir))
+ if ((disk_kind != svn_node_none)
+ && (disk_kind != svn_node_file)
+ && (disk_kind != svn_node_dir))
return svn_error_createf
(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
_("Cannot revert '%s': unsupported node kind in working copy"),
@@ -2169,8 +2051,8 @@ revert_internal(svn_wc__db_t *db,
/* Actually revert this entry. If this is a working copy root,
we provide a base_name from the parent path. */
- if (entry)
- SVN_ERR(revert_entry(&depth, db, local_abspath, kind, entry,
+ if (!unversioned)
+ SVN_ERR(revert_entry(&depth, db, local_abspath, disk_kind,
use_commit_times,
cancel_func, cancel_baton,
&reverted, pool));
@@ -2184,7 +2066,7 @@ revert_internal(svn_wc__db_t *db,
}
/* Finally, recurse if requested. */
- if (entry && entry->kind == svn_node_dir && depth > svn_depth_empty)
+ if (!unversioned && db_kind == svn_wc__db_kind_dir && depth > svn_depth_empty)
{
const apr_array_header_t *children;
apr_hash_t *nodes = apr_hash_make(pool);
@@ -2203,7 +2085,7 @@ revert_internal(svn_wc__db_t *db,
const char *name = APR_ARRAY_IDX(children, i, const char *);
const char *node_abspath;
svn_boolean_t hidden;
- svn_wc__db_kind_t db_kind;
+ svn_wc__db_kind_t child_db_kind;
svn_pool_clear(iterpool);
@@ -2216,13 +2098,13 @@ revert_internal(svn_wc__db_t *db,
apr_hash_set(nodes, name, APR_HASH_KEY_STRING, name);
- SVN_ERR(svn_wc__db_read_kind(&db_kind, db, node_abspath, FALSE,
+ SVN_ERR(svn_wc__db_read_kind(&child_db_kind, db, node_abspath, FALSE,
iterpool));
/* Skip subdirectories if we're called with depth-files. */
if ((depth == svn_depth_files) &&
- (db_kind != svn_wc__db_kind_file) &&
- (db_kind != svn_wc__db_kind_symlink))
+ (child_db_kind != svn_wc__db_kind_file) &&
+ (child_db_kind != svn_wc__db_kind_symlink))
continue;
/* Revert the entry. */
@@ -2234,34 +2116,48 @@ revert_internal(svn_wc__db_t *db,
/* Visit any unversioned children that are tree conflict victims. */
{
- apr_hash_t *conflicts;
- apr_hash_index_t *hi2;
+ const apr_array_header_t *conflict_victims;
/* Loop through all the tree conflict victims */
- SVN_ERR(svn_wc__read_tree_conflicts(&conflicts,
- entry->tree_conflict_data,
- path, pool));
+ SVN_ERR(svn_wc__db_read_conflict_victims(&conflict_victims,
+ db, local_abspath,
+ pool, pool));
- for (hi2 = apr_hash_first(pool, conflicts); hi2;
- hi2 = apr_hash_next(hi2))
+ for (i = 0; i < conflict_victims->nelts; ++i)
{
- const svn_wc_conflict_description2_t *conflict =
- svn_apr_hash_index_val(hi2);
+ int j;
+ const apr_array_header_t *child_conflicts;
+ const char *child_name;
+ const char *child_abspath;
svn_pool_clear(iterpool);
- /* If this victim is not in this dir's entries ... */
- if (apr_hash_get(nodes,
- svn_dirent_basename(conflict->local_abspath,
- pool),
- APR_HASH_KEY_STRING) == NULL)
+ child_name = APR_ARRAY_IDX(conflict_victims, i, const char *);
+
+ /* Skip if in this dir's entries, we only want unversioned */
+ if (apr_hash_get(nodes, child_name, APR_HASH_KEY_STRING))
+ continue;
+
+ child_abspath = svn_dirent_join(local_abspath, child_name,
+ iterpool);
+
+ SVN_ERR(svn_wc__db_read_conflicts(&child_conflicts,
+ db, child_abspath,
+ iterpool, iterpool));
+
+ for (j = 0; j < child_conflicts->nelts; ++j)
{
- /* Revert the entry. */
- SVN_ERR(revert_internal(db, conflict->local_abspath,
- svn_depth_empty,
- use_commit_times, changelist_hash,
- cancel_func, cancel_baton,
- notify_func, notify_baton, iterpool));
+ const svn_wc_conflict_description2_t *conflict =
+ APR_ARRAY_IDX(child_conflicts, j,
+ const svn_wc_conflict_description2_t *);
+
+ if (conflict->kind == svn_wc_conflict_kind_tree)
+ SVN_ERR(revert_internal(db, conflict->local_abspath,
+ svn_depth_empty,
+ use_commit_times, changelist_hash,
+ cancel_func, cancel_baton,
+ notify_func, notify_baton,
+ iterpool));
}
}
}
@@ -2304,15 +2200,17 @@ svn_wc_get_pristine_copy_path(const char
const char **pristine_path,
apr_pool_t *pool)
{
- svn_wc_context_t *wc_ctx;
+ svn_wc__db_t *db;
const char *local_abspath;
- SVN_ERR(svn_wc_context_create(&wc_ctx, NULL, pool, pool));
+ 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, wc_ctx->db, local_abspath,
- FALSE, pool));
- return SVN_NO_ERROR;
+ SVN_ERR(svn_wc__text_base_path(pristine_path, db, local_abspath,
+ FALSE, pool));
+
+ return svn_error_return(svn_wc__db_close(db));
}
svn_error_t *
@@ -2336,19 +2234,76 @@ svn_wc__get_pristine_contents(svn_stream
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- const char *text_base;
+ svn_wc__db_status_t status;
+ svn_wc__db_kind_t kind;
- SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath, FALSE,
- scratch_pool));
+ 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 (text_base == NULL)
+ if (status == svn_wc__db_status_added)
{
- *contents = NULL;
- return SVN_NO_ERROR;
+ /* 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_stream_open_readonly(contents, text_base, result_pool,
- scratch_pool);
+ return svn_error_return(svn_stream_open_readonly(contents, text_base,
+ result_pool,
+ scratch_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=984153&r1=984152&r2=984153&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 18:06:17 2010
@@ -115,6 +115,7 @@ struct dir_baton
void *wrapped_baton;
};
+/* */
static svn_error_t *
make_dir_baton(struct dir_baton **d_p,
const char *path,
@@ -206,6 +207,7 @@ make_dir_baton(struct dir_baton **d_p,
return SVN_NO_ERROR;
}
+/* */
static svn_error_t *
make_file_baton(struct file_baton **f_p,
struct dir_baton *pb,
@@ -264,6 +266,7 @@ make_file_baton(struct file_baton **f_p,
/*** Editor Functions ***/
+/* */
static svn_error_t *
set_target_revision(void *edit_baton,
svn_revnum_t target_revision,
@@ -276,6 +279,7 @@ set_target_revision(void *edit_baton,
target_revision, pool);
}
+/* */
static svn_error_t *
open_root(void *edit_baton,
svn_revnum_t base_revision,
@@ -322,6 +326,7 @@ open_root(void *edit_baton,
pool, &b->wrapped_baton);
}
+/* */
static svn_error_t *
delete_entry(const char *path,
svn_revnum_t base_revision,
@@ -361,6 +366,7 @@ delete_entry(const char *path,
pb->wrapped_baton, pool);
}
+/* */
static svn_error_t *
add_directory(const char *path,
void *parent_baton,
@@ -406,6 +412,7 @@ add_directory(const char *path,
pool, &b->wrapped_baton);
}
+/* */
static svn_error_t *
open_directory(const char *path,
void *parent_baton,
@@ -458,6 +465,7 @@ open_directory(const char *path,
return SVN_NO_ERROR;
}
+/* */
static svn_error_t *
add_file(const char *path,
void *parent_baton,
@@ -481,6 +489,7 @@ add_file(const char *path,
pool, &b->wrapped_baton);
}
+/* */
static svn_error_t *
open_file(const char *path,
void *parent_baton,
@@ -502,6 +511,7 @@ open_file(const char *path,
&b->wrapped_baton);
}
+/* */
static svn_error_t *
apply_textdelta(void *file_baton,
const char *base_checksum,
@@ -525,6 +535,7 @@ apply_textdelta(void *file_baton,
handler, handler_baton);
}
+/* */
static svn_error_t *
close_file(void *file_baton,
const char *text_checksum,
@@ -540,6 +551,7 @@ close_file(void *file_baton,
text_checksum, pool);
}
+/* */
static svn_error_t *
absent_file(const char *path,
void *parent_baton,
@@ -554,6 +566,7 @@ absent_file(const char *path,
return eb->wrapped_editor->absent_file(path, pb->wrapped_baton, pool);
}
+/* */
static svn_error_t *
close_directory(void *dir_baton,
apr_pool_t *pool)
@@ -567,6 +580,7 @@ close_directory(void *dir_baton,
return eb->wrapped_editor->close_directory(db->wrapped_baton, pool);
}
+/* */
static svn_error_t *
absent_directory(const char *path,
void *parent_baton,
@@ -582,6 +596,7 @@ absent_directory(const char *path,
return eb->wrapped_editor->absent_directory(path, pb->wrapped_baton, pool);
}
+/* */
static svn_error_t *
change_file_prop(void *file_baton,
const char *name,
@@ -598,6 +613,7 @@ change_file_prop(void *file_baton,
name, value, pool);
}
+/* */
static svn_error_t *
change_dir_prop(void *dir_baton,
const char *name,
@@ -614,6 +630,7 @@ change_dir_prop(void *dir_baton,
name, value, pool);
}
+/* */
static svn_error_t *
close_edit(void *edit_baton,
apr_pool_t *pool)
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=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/conflicts.c Tue Aug 10 18:06:17 2010
@@ -67,6 +67,7 @@ struct svn_wc_conflict_t
/* ### TODO: Add more fields */
};
+/* */
static svn_error_t *
conflict_alloc(svn_wc_conflict_t **conflict, apr_pool_t *result_pool)
{
@@ -427,6 +428,7 @@ resolve_conflict_on_node(svn_wc__db_t *d
return SVN_NO_ERROR;
}
+/* */
static svn_error_t *
resolve_one_conflict(svn_wc__db_t *db,
const char *local_abspath,
@@ -545,6 +547,7 @@ resolve_one_conflict(svn_wc__db_t *db,
return SVN_NO_ERROR;
}
+/* */
static svn_error_t *
recursive_resolve_conflict(svn_wc__db_t *db,
const char *local_abspath,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/copy.c Tue Aug 10 18:06:17 2010
@@ -60,8 +60,8 @@ copy_props(svn_wc__db_t *db,
scratch_pool, scratch_pool));
for (hi = apr_hash_first(scratch_pool, props); hi; hi = apr_hash_next(hi))
{
- const char *propname = svn_apr_hash_index_key(hi);
- svn_string_t *propval = svn_apr_hash_index_val(hi);
+ const char *propname = svn__apr_hash_index_key(hi);
+ svn_string_t *propval = svn__apr_hash_index_val(hi);
SVN_ERR(svn_wc__internal_propset(db, dst_abspath, propname, propval,
FALSE /* skip_checks */,
@@ -188,8 +188,8 @@ copy_added_dir_administratively(svn_wc_c
hi;
hi = apr_hash_next(hi))
{
- const char *name = svn_apr_hash_index_key(hi);
- svn_io_dirent_t *dirent = svn_apr_hash_index_val(hi);
+ const char *name = svn__apr_hash_index_key(hi);
+ svn_io_dirent_t *dirent = svn__apr_hash_index_val(hi);
const char *node_abspath;
svn_wc__db_kind_t kind;
@@ -402,9 +402,16 @@ copy_file_administratively(svn_wc_contex
scratch_pool, scratch_pool));
/* Sanity check 2: You cannot make a copy of something that's not
- in the repository unless it's a copy of an uncommitted copy. */
- if ((src_entry->schedule == svn_wc_schedule_add && (! src_entry->copied))
- || (! src_entry->url))
+ in the repository unless it's a copy of an uncommitted copy.
+ Added files don't have a base, but replaced files have a revert-base.
+ ### TODO: svn_opt_revision_base currently means "commit-base", which
+ ### technically is none for replaced files. We currently have no way to
+ ### get at the revert-base and need a new svn_opt_revision_X for that.
+ */
+ if (((src_entry->schedule == svn_wc_schedule_add
+ || src_entry->schedule == svn_wc_schedule_replace)
+ && (!src_entry->copied))
+ || (!src_entry->url))
return svn_error_createf
(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
_("Cannot copy or move '%s': it is not in the repository yet; "
@@ -484,6 +491,10 @@ copy_file_administratively(svn_wc_contex
err, NULL);
else if (err)
return svn_error_return(err);
+
+ /* Above add/replace condition should have caught this already
+ * (-> error "Cannot copy..."). */
+ SVN_ERR_ASSERT(contents != NULL);
}
else if (err)
return svn_error_return(err);
@@ -513,6 +524,9 @@ copy_file_administratively(svn_wc_contex
SVN_ERR(svn_wc_get_pristine_contents2(&base_contents, wc_ctx, src_abspath,
scratch_pool, scratch_pool));
+ /* Above add/replace condition should have caught this already
+ * (-> error "Cannot copy..."). */
+ SVN_ERR_ASSERT(base_contents != NULL);
SVN_ERR(svn_wc_add_repos_file4(wc_ctx, dst_abspath,
base_contents, contents,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/deprecated.c Tue Aug 10 18:06:17 2010
@@ -30,6 +30,7 @@
#include "svn_subst.h"
#include "svn_pools.h"
#include "svn_props.h"
+#include "svn_time.h"
#include "svn_dirent_uri.h"
#include "private/svn_wc_private.h"
@@ -37,6 +38,7 @@
#include "wc.h"
#include "lock.h"
#include "props.h"
+#include "workqueue.h"
#include "svn_private_config.h"
@@ -163,6 +165,7 @@ struct wrap_3to2_report_baton {
void *baton;
};
+/* */
static svn_error_t *wrap_3to2_set_path(void *report_baton,
const char *path,
svn_revnum_t revision,
@@ -177,6 +180,7 @@ static svn_error_t *wrap_3to2_set_path(v
lock_token, pool);
}
+/* */
static svn_error_t *wrap_3to2_delete_path(void *report_baton,
const char *path,
apr_pool_t *pool)
@@ -186,6 +190,7 @@ static svn_error_t *wrap_3to2_delete_pat
return wrb->reporter->delete_path(wrb->baton, path, pool);
}
+/* */
static svn_error_t *wrap_3to2_link_path(void *report_baton,
const char *path,
const char *url,
@@ -201,6 +206,7 @@ static svn_error_t *wrap_3to2_link_path(
start_empty, lock_token, pool);
}
+/* */
static svn_error_t *wrap_3to2_finish_report(void *report_baton,
apr_pool_t *pool)
{
@@ -209,6 +215,7 @@ static svn_error_t *wrap_3to2_finish_rep
return wrb->reporter->finish_report(wrb->baton, pool);
}
+/* */
static svn_error_t *wrap_3to2_abort_report(void *report_baton,
apr_pool_t *pool)
{
@@ -296,6 +303,7 @@ struct wrap_2to1_report_baton {
void *baton;
};
+/* */
static svn_error_t *wrap_2to1_set_path(void *report_baton,
const char *path,
svn_revnum_t revision,
@@ -309,6 +317,7 @@ static svn_error_t *wrap_2to1_set_path(v
pool);
}
+/* */
static svn_error_t *wrap_2to1_delete_path(void *report_baton,
const char *path,
apr_pool_t *pool)
@@ -318,6 +327,7 @@ static svn_error_t *wrap_2to1_delete_pat
return wrb->reporter->delete_path(wrb->baton, path, pool);
}
+/* */
static svn_error_t *wrap_2to1_link_path(void *report_baton,
const char *path,
const char *url,
@@ -332,6 +342,7 @@ static svn_error_t *wrap_2to1_link_path(
start_empty, pool);
}
+/* */
static svn_error_t *wrap_2to1_finish_report(void *report_baton,
apr_pool_t *pool)
{
@@ -340,6 +351,7 @@ static svn_error_t *wrap_2to1_finish_rep
return wrb->reporter->finish_report(wrb->baton, pool);
}
+/* */
static svn_error_t *wrap_2to1_abort_report(void *report_baton,
apr_pool_t *pool)
{
@@ -537,6 +549,49 @@ svn_wc_get_pristine_contents(svn_stream_
svn_error_t *
+svn_wc_process_committed4(const char *path,
+ svn_wc_adm_access_t *adm_access,
+ svn_boolean_t recurse,
+ svn_revnum_t new_revnum,
+ const char *rev_date,
+ const char *rev_author,
+ const apr_array_header_t *wcprop_changes,
+ svn_boolean_t remove_lock,
+ svn_boolean_t remove_changelist,
+ const unsigned char *digest,
+ apr_pool_t *pool)
+{
+ svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
+ const char *local_abspath;
+ const svn_checksum_t *checksum;
+ apr_time_t new_date;
+ apr_hash_t *wcprop_changes_hash;
+
+ if (rev_date)
+ SVN_ERR(svn_time_from_cstring(&new_date, rev_date, pool));
+ else
+ new_date = 0;
+
+ if (digest)
+ checksum = svn_checksum__from_digest(digest, svn_checksum_md5, pool);
+ else
+ checksum = NULL;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
+
+ wcprop_changes_hash = svn_wc__prop_array_to_hash(wcprop_changes, pool);
+ SVN_ERR(svn_wc__process_committed_internal(db, local_abspath, recurse,
+ new_revnum, new_date, rev_author,
+ wcprop_changes_hash,
+ !remove_lock, !remove_changelist,
+ checksum, NULL, pool));
+
+ /* Run the log file(s) we just created. */
+ return svn_error_return(svn_wc__wq_run(db, local_abspath, NULL, NULL, pool));
+}
+
+
+svn_error_t *
svn_wc_process_committed3(const char *path,
svn_wc_adm_access_t *adm_access,
svn_boolean_t recurse,
@@ -2171,6 +2226,7 @@ struct status4_wrapper_baton
const char *anchor_relpath;
};
+/* */
static svn_error_t *
status4_wrapper_func(void *baton,
const char *local_abspath,
@@ -2267,6 +2323,7 @@ struct status_editor3_compat_baton
void *old_baton;
};
+/* */
static svn_error_t *
status_editor3_compat_func(void *baton,
const char *path,
@@ -2289,7 +2346,7 @@ svn_wc_get_status_editor3(const svn_delt
svn_depth_t depth,
svn_boolean_t get_all,
svn_boolean_t no_ignore,
- apr_array_header_t *ignore_patterns,
+ const apr_array_header_t *ignore_patterns,
svn_wc_status_func2_t status_func,
void *status_baton,
svn_cancel_func_t cancel_func,
@@ -2356,6 +2413,7 @@ struct old_status_func_cb_baton
void *original_baton;
};
+/* */
static void old_status_func_cb(void *baton,
const char *path,
svn_wc_status2_t *status)
@@ -2671,7 +2729,7 @@ svn_wc_get_update_editor3(svn_revnum_t *
svn_wc_get_file_t fetch_func,
void *fetch_baton,
const char *diff3_cmd,
- apr_array_header_t *preserved_exts,
+ const apr_array_header_t *preserved_exts,
const svn_delta_editor_t **editor,
void **edit_baton,
svn_wc_traversal_info_t *traversal_info,
@@ -2786,7 +2844,7 @@ svn_wc_get_switch_editor3(svn_revnum_t *
svn_wc_conflict_resolver_func_t conflict_func,
void *conflict_baton,
const char *diff3_cmd,
- apr_array_header_t *preserved_exts,
+ const apr_array_header_t *preserved_exts,
const svn_delta_editor_t **editor,
void **edit_baton,
svn_wc_traversal_info_t *traversal_info,
@@ -3643,3 +3701,68 @@ svn_wc_crop_tree(svn_wc_adm_access_t *an
return svn_error_return(svn_wc_context_destroy(wc_ctx));
}
+
+svn_error_t *
+svn_wc_queue_committed2(svn_wc_committed_queue_t *queue,
+ const char *path,
+ svn_wc_adm_access_t *adm_access,
+ svn_boolean_t recurse,
+ const apr_array_header_t *wcprop_changes,
+ svn_boolean_t remove_lock,
+ svn_boolean_t remove_changelist,
+ const svn_checksum_t *checksum,
+ apr_pool_t *scratch_pool)
+{
+ const char *local_abspath;
+
+ SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, scratch_pool));
+ return svn_wc_queue_committed3(queue, local_abspath, recurse, wcprop_changes,
+ remove_lock, remove_changelist, checksum,
+ scratch_pool);
+}
+
+svn_error_t *
+svn_wc_queue_committed(svn_wc_committed_queue_t **queue,
+ const char *path,
+ svn_wc_adm_access_t *adm_access,
+ svn_boolean_t recurse,
+ const apr_array_header_t *wcprop_changes,
+ svn_boolean_t remove_lock,
+ svn_boolean_t remove_changelist,
+ const unsigned char *digest,
+ apr_pool_t *pool)
+{
+ const svn_checksum_t *checksum;
+
+ if (digest)
+ checksum = svn_checksum__from_digest(
+ digest, svn_checksum_md5,
+ svn_wc__get_committed_queue_pool(*queue));
+ else
+ checksum = NULL;
+
+ return svn_wc_queue_committed2(*queue, path, adm_access, recurse,
+ wcprop_changes, remove_lock,
+ remove_changelist, checksum, pool);
+}
+
+svn_error_t *
+svn_wc_process_committed_queue(svn_wc_committed_queue_t *queue,
+ svn_wc_adm_access_t *adm_access,
+ svn_revnum_t new_revnum,
+ const char *rev_date,
+ const char *rev_author,
+ apr_pool_t *pool)
+{
+ svn_wc_context_t *wc_ctx;
+
+ SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
+ svn_wc__adm_get_db(adm_access),
+ pool));
+ SVN_ERR(svn_wc_process_committed_queue2(queue, wc_ctx, new_revnum,
+ rev_date, rev_author, pool));
+ SVN_ERR(svn_wc_context_destroy(wc_ctx));
+
+ return SVN_NO_ERROR;
+}
+
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c?rev=984153&r1=984152&r2=984153&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/diff.c Tue Aug 10 18:06:17 2010
@@ -514,7 +514,7 @@ get_working_mimetype(const char **mimety
*/
static apr_hash_t *
apply_propchanges(apr_hash_t *props,
- apr_array_header_t *propchanges)
+ const apr_array_header_t *propchanges)
{
apr_hash_t *newprops = apr_hash_copy(apr_hash_pool_get(props), props);
int i;
@@ -1501,6 +1501,8 @@ apply_textdelta(void *file_baton,
/* The current text-base is the starting point if replacing */
SVN_ERR(svn_wc__get_pristine_contents(&source, eb->db, fb->local_abspath,
fb->pool, fb->pool));
+ if (source == NULL)
+ source = svn_stream_empty(fb->pool);
}
/* This is the file that will contain the pristine repository version. It
@@ -1549,7 +1551,6 @@ close_file(void *file_baton,
const char *localfile;
/* The path to the temporary copy of the pristine repository version. */
const char *temp_file_path;
- const char *temp_file_abspath;
svn_boolean_t modified;
/* The working copy properties at the base of the wc->repos
comparison: either BASE or WORKING. */
@@ -1588,8 +1589,6 @@ close_file(void *file_baton,
if (!temp_file_path)
SVN_ERR(svn_wc__text_base_path(&temp_file_path, eb->db, fb->local_abspath,
FALSE, fb->pool));
- SVN_ERR(svn_dirent_get_absolute(&temp_file_abspath, temp_file_path,
- fb->pool));
/* If the file isn't in the working copy (either because it was added
in the BASE->repos diff or because we're diffing against WORKING