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/11 00:07:31 UTC

svn commit: r984234 [10/20] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/ac-macros/ build/generator/ notes/ notes/api-errata/ notes/obliterate/ notes/obliterate/fspec-cc1/ notes/rename-tracking/ notes/svnpatch/ notes/tree-conflicts/ note...

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.c Tue Aug 10 22:07:24 2010
@@ -158,22 +158,6 @@ svn_wc__entry_is_hidden(svn_boolean_t *h
 }
 
 
-/* */
-static svn_error_t *
-fetch_wc_id(apr_int64_t *wc_id, svn_sqlite__db_t *sdb)
-{
-  svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WCROOT_NULL));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  if (!have_row)
-    return svn_error_create(SVN_ERR_WC_DB_ERROR, NULL, _("No WC table entry"));
-  *wc_id = svn_sqlite__column_int(stmt, 0);
-  return svn_error_return(svn_sqlite__reset(stmt));
-}
-
-
 /* Hit the database to check the file external information for the given
    entry.  The entry will be modified in place. */
 static svn_error_t *
@@ -523,7 +507,7 @@ read_one_entry(const svn_wc_entry_t **ne
   const char *original_repos_relpath;
   const char *original_root_url;
   svn_boolean_t conflicted;
-  svn_boolean_t base_shadowed;
+  svn_boolean_t have_base;
 
   entry->name = name;
 
@@ -550,8 +534,8 @@ read_one_entry(const svn_wc_entry_t **ne
             NULL,
             &entry->copyfrom_rev,
             NULL,
+            &have_base,
             NULL,
-            &base_shadowed,
             &conflicted,
             &lock,
             db,
@@ -706,7 +690,7 @@ read_one_entry(const svn_wc_entry_t **ne
           entry->revision = parent_entry->revision;
         }
 
-      if (base_shadowed)
+      if (have_base)
         {
           svn_wc__db_status_t base_status;
 
@@ -808,6 +792,13 @@ read_one_entry(const svn_wc_entry_t **ne
                                            db,
                                            entry_abspath,
                                            result_pool, scratch_pool));
+
+          /* In wc.db we want to keep the valid revision of the not-present 
+             BASE_REV, but when we used entries we set the revision to 0
+             when adding a new node over a not present base node. */
+          if (work_status == svn_wc__db_status_added
+              && entry->deleted)
+            entry->revision = 0;
         }
 
       if (!SVN_IS_VALID_REVNUM(entry->cmt_rev)
@@ -1383,7 +1374,7 @@ get_entry_access_info(const char **adm_a
       /* FILE node needs to read the parent directory. Or a DIR node
          needs to read from the parent to get at the stub entry. Or this
          is an UNKNOWN node, and we need to examine the parent.  */
-      svn_dirent_split(local_abspath, adm_abspath, entry_name, result_pool);
+      svn_dirent_split(adm_abspath, entry_name, local_abspath, result_pool);
     }
 
   return SVN_NO_ERROR;
@@ -1518,84 +1509,6 @@ svn_wc__get_entry(const svn_wc_entry_t *
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_wc__get_entry_versioned(const svn_wc_entry_t **entry,
-                            svn_wc_context_t *wc_ctx,
-                            const char *local_abspath,
-                            svn_node_kind_t kind,
-                            svn_boolean_t show_hidden,
-                            svn_boolean_t need_parent_stub,
-                            apr_pool_t *result_pool,
-                            apr_pool_t *scratch_pool)
-{
-  svn_error_t *err;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  /* We call this with allow_unversioned=TRUE, since the error returned is
-     different than our callers currently expect.  We catch the NULL entry
-     below and return the correct error. */
-  err = svn_wc__get_entry(entry, wc_ctx->db, local_abspath, TRUE, kind,
-                          need_parent_stub, result_pool, scratch_pool);
-  if (err && (err->apr_err == SVN_ERR_WC_MISSING
-                || err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND
-                || err->apr_err == SVN_ERR_NODE_UNEXPECTED_KIND))
-    {
-      svn_error_clear(err);
-      *entry = NULL;
-    }
-  else if (err)
-    return svn_error_return(err);
-
-
-  if (*entry && !show_hidden)
-    {
-      svn_boolean_t hidden;
-
-      SVN_ERR(svn_wc__entry_is_hidden(&hidden, *entry));
-      if (hidden)
-        *entry = NULL;
-    }
-
-  if (! *entry)
-    return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL,
-                             _("'%s' is not under version control"),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_wc__node_is_deleted(svn_boolean_t *deleted,
-                        svn_wc__db_t *db,
-                        const char *local_abspath,
-                        apr_pool_t *scratch_pool)
-{
-  const svn_wc_entry_t *entry;
-  svn_error_t *err;
-
-  /* ### rewrite this in terms of wc_db.  */
-
-  err = svn_wc__get_entry(&entry, db, local_abspath, FALSE,
-                          svn_node_unknown, TRUE, scratch_pool, scratch_pool);
-  if (err)
-    {
-      if (err->apr_err != SVN_ERR_NODE_UNEXPECTED_KIND)
-        return svn_error_return(err);
-
-      /* We asked for the parent stub, but got a file. No big deal. We have
-         what we wanted for a file.  */
-      svn_error_clear(err);
-    }
-
-  *deleted = entry->deleted;
-  return SVN_NO_ERROR;
-}
-
-
 /* TODO ### Rewrite doc string to mention ENTRIES_ALL; not ADM_ACCESS.
 
    Prune the deleted entries from the cached entries in ADM_ACCESS, and
@@ -2385,672 +2298,6 @@ svn_wc__write_upgraded_entries(svn_wc__d
                                    scratch_pool));
 }
 
-struct write_one_entry_baton
-{
-  svn_wc__db_t *db;
-  const char *local_abspath;
-  const svn_wc_entry_t *this_dir;
-  const svn_wc_entry_t *this_entry;
-};
-
-/* Rewrites a single entry inside a sqlite transaction
-   Implements svn_sqlite__transaction_callback_t. */
-static svn_error_t *
-write_one_entry_cb(void *baton,
-                   svn_sqlite__db_t *sdb,
-                   apr_pool_t *scratch_pool)
-{
-  struct write_one_entry_baton *woeb = baton;
-  svn_wc__db_t *db = woeb->db;
-  const char *local_abspath = woeb->local_abspath;
-  const svn_wc_entry_t *this_dir = woeb->this_dir;
-  const svn_wc_entry_t *this_entry = woeb->this_entry;
-  const char *this_abspath = svn_dirent_join(local_abspath, this_entry->name,
-                                             scratch_pool);
-  const void *base_props = NULL;
-  const void *working_props = NULL;
-  const void *actual_props = NULL;
-  apr_size_t base_prop_len;
-  apr_size_t working_prop_len;
-  apr_size_t actual_prop_len;
-  apr_hash_t *dav_cache;
-  const svn_checksum_t *base_checksum;
-  svn_sqlite__stmt_t *stmt;
-  const char *repos_root;
-  apr_int64_t repos_id;
-  apr_int64_t wc_id;
-  svn_error_t *err;
-  svn_boolean_t got_row;
-
-  SVN_ERR_ASSERT(this_dir && this_entry);
-
-  /* Get the repos ID. */
-  if (this_dir->uuid != NULL)
-    {
-      /* ### does this need to be done on a per-entry basis instead of
-         ### the per-directory way we do it now?  me thinks yes...
-         ###
-         ### when do we harvest repository entries which no longer have
-         ### any members?  */
-      SVN_ERR(svn_wc__db_repos_ensure(&repos_id, db, local_abspath,
-                                      this_dir->repos, this_dir->uuid,
-                                      scratch_pool));
-      repos_root = this_dir->repos;
-    }
-  else
-    {
-      repos_id = 0;
-      repos_root = NULL;
-    }
-
-  SVN_ERR(fetch_wc_id(&wc_id, sdb));
-
-  /* Before we nuke all the nodes, we need to get a few values */
-
-  /* The dav cache is not in STMT_SELECT_BASE_NODE */
-  err = svn_wc__db_base_get_dav_cache(&dav_cache, db, this_abspath,
-                                      scratch_pool, scratch_pool);
-  if (err)
-    {
-      if (err->apr_err != SVN_ERR_WC_PATH_NOT_FOUND)
-        return svn_error_return(err);
-      svn_error_clear(err); /* No BASE record */
-      dav_cache = NULL;
-    }
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_BASE_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, this_entry->name));
-  SVN_ERR(svn_sqlite__step(&got_row, stmt));
-  if (got_row)
-    {
-      base_props = svn_sqlite__column_blob(stmt, 13, &base_prop_len,
-                                           scratch_pool);
-
-      err = svn_sqlite__column_checksum(&base_checksum, stmt, 5, scratch_pool);
-      /* ### SVN_EXPERIMENTAL_PRISTINE:
-         base_checksum is originally MD-5 but will later be SHA-1.  The
-         base_checksum is not yet handled by this function. */
-
-      SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt)));
-    }
-  else
-    SVN_ERR(svn_sqlite__reset(stmt));
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WORKING_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, this_entry->name));
-  SVN_ERR(svn_sqlite__step(&got_row, stmt));
-  if (got_row)
-    {
-      /* No need to store the working checksum, that is stored in the entry */
-      working_props = svn_sqlite__column_blob(stmt, 15, &working_prop_len,
-                                              scratch_pool);
-    }
-  SVN_ERR(svn_sqlite__reset(stmt));
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ACTUAL_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, this_entry->name));
-  SVN_ERR(svn_sqlite__step(&got_row, stmt));
-  if (got_row)
-    {
-      actual_props = svn_sqlite__column_blob(stmt, 6, &actual_prop_len,
-                                             scratch_pool);
-    }
-  SVN_ERR(svn_sqlite__reset(stmt));
-
-  /* Remove the WORKING, BASE and ACTUAL nodes for this entry */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_WORKING_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, this_entry->name));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_BASE_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, this_entry->name));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_DELETE_ACTUAL_NODE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, this_entry->name));
-  SVN_ERR(svn_sqlite__step_done(stmt));
-
-  SVN_ERR(write_entry(db, sdb, wc_id, repos_id, repos_root, this_entry,
-                      this_entry->name, this_abspath, this_dir,
-                      actual_props != NULL, FALSE, scratch_pool));
-
-  if (dav_cache)
-    SVN_ERR(svn_wc__db_base_set_dav_cache(db, this_abspath, dav_cache,
-                                          scratch_pool));
-
-  if (base_props)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_BASE_PROPS));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isb", wc_id, this_entry->name,
-                                base_props, base_prop_len));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-
-  if (working_props)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                        STMT_UPDATE_WORKING_PROPS));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isb", wc_id, this_entry->name,
-                                working_props, working_prop_len));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-
-  if (actual_props)
-    {
-      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                        STMT_UPDATE_ACTUAL_PROPS));
-      SVN_ERR(svn_sqlite__bindf(stmt, "isb", wc_id, this_entry->name,
-                                actual_props, actual_prop_len));
-      SVN_ERR(svn_sqlite__step_done(stmt));
-    }
-
-  /* TODO: Update base checksum if needed */
-  return SVN_NO_ERROR;
-}
-
-/* */
-static svn_error_t *
-write_one_entry(svn_wc__db_t *db,
-                const char *local_abspath,
-                const svn_wc_entry_t *this_dir,
-                const svn_wc_entry_t *this_entry,
-                apr_pool_t *scratch_pool)
-{
-  struct write_one_entry_baton woeb;
-  svn_sqlite__db_t *sdb;
-
-  /* ### need the SDB so we can jam rows directly into it.  */
-  SVN_ERR(svn_wc__db_temp_borrow_sdb(&sdb, db, local_abspath,
-                                     svn_wc__db_openmode_readwrite,
-                                     scratch_pool));
-  woeb.db = db;
-  woeb.local_abspath = local_abspath;
-  woeb.this_dir = this_dir;
-  woeb.this_entry = this_entry;
-
-  /* Run this operation in a transaction to speed up SQLite.
-     See http://www.sqlite.org/faq.html#q19 for more details */
-  return svn_error_return(
-      svn_sqlite__with_transaction(sdb, write_one_entry_cb, &woeb,
-                                   scratch_pool));
-}
-
-
-
-/* Update the entry CUR_ENTRY, according to the combination of
-   entry data found in ENTRY and masked by MODIFY_FLAGS.
-   The requested changes will be folded (merged) into
-   the entry's existing state.
-   Also cleanups meaningless fields combinations.
-
-   PARENT_ENTRY must be passed, in order to grab certain "default" values.
-
-   POOL will be used to allocate memory referenced by ENTRIES.
- */
-static svn_error_t *
-fold_entry(svn_wc_entry_t *cur_entry,
-           const char *name,
-           int modify_flags,
-           const svn_wc_entry_t *entry,
-           const svn_wc_entry_t *parent_entry,
-           apr_pool_t *pool)
-{
-  SVN_ERR_ASSERT(cur_entry != NULL);
-  SVN_ERR_ASSERT(name != NULL);
-  SVN_ERR_ASSERT(entry != NULL);
-
-  /* Name (just a safeguard here, really) */
-  if (! cur_entry->name)
-    cur_entry->name = apr_pstrdup(pool, name);
-
-  /* Revision */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_REVISION)
-    cur_entry->revision = entry->revision;
-
-  /* Ancestral URL in repository */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_URL)
-    cur_entry->url = entry->url ? apr_pstrdup(pool, entry->url) : NULL;
-
-  /* Kind */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_KIND)
-    cur_entry->kind = entry->kind;
-
-  /* Schedule: handled by caller.  */
-
-  /* Checksum */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CHECKSUM)
-    cur_entry->checksum = entry->checksum
-      ? apr_pstrdup(pool, entry->checksum)
-                          : NULL;
-
-  /* Copy-related stuff */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_COPIED)
-    cur_entry->copied = entry->copied;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_COPYFROM_URL)
-    cur_entry->copyfrom_url = entry->copyfrom_url
-      ? apr_pstrdup(pool, entry->copyfrom_url)
-                              : NULL;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_COPYFROM_REV)
-    cur_entry->copyfrom_rev = entry->copyfrom_rev;
-
-  /* Deleted state */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_DELETED)
-    cur_entry->deleted = entry->deleted;
-
-  /* Absent state */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_ABSENT)
-    cur_entry->absent = entry->absent;
-
-  /* text_time, prop_time no longer passed to entry_modify()  */
-
-  /* Conflict stuff */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CONFLICT_OLD)
-    cur_entry->conflict_old = entry->conflict_old
-      ? apr_pstrdup(pool, entry->conflict_old)
-                              : NULL;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CONFLICT_NEW)
-    cur_entry->conflict_new = entry->conflict_new
-      ? apr_pstrdup(pool, entry->conflict_new)
-                              : NULL;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CONFLICT_WRK)
-    cur_entry->conflict_wrk = entry->conflict_wrk
-      ? apr_pstrdup(pool, entry->conflict_wrk)
-                              : NULL;
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_PREJFILE)
-    cur_entry->prejfile = entry->prejfile
-      ? apr_pstrdup(pool, entry->prejfile)
-                          : NULL;
-
-  /* Last-commit flags are no longer passed to entry_modify() */
-
-  /* LOCK flags are no longer passed to entry_modify().  */
-
-  /* changelist is no longer modified with this function.  */
-
-  /* has-props, prop-mods, cachable-props, and present-props are deprecated,
-     so we do not copy them. */
-
-  /* keep_local is no longer modified with this function */
-
-  /* Note that we don't bother to fold entry->depth, because it is
-     only meaningful on the this-dir entry anyway. */
-
-  /* tree_conflict_data is never modified via entry_t.  */
-
-  /* Absorb defaults from the parent dir, if any, unless this is a
-     subdir entry. */
-  if (cur_entry->kind != svn_node_dir && parent_entry != NULL)
-    {
-      if ((cur_entry->revision == SVN_INVALID_REVNUM) 
-          && (cur_entry->kind != svn_node_dir))
-        cur_entry->revision = parent_entry->revision;
-    }
-
-  /* Cleanup meaningless fields */
-
-  /* ### svn_wc_schedule_delete is the minimal value. We need it because it's
-     impossible to NULLify copyfrom_url with log-instructions.
-
-     Note that I tried to find the smallest collection not to clear these
-     fields for, but this condition still fails the test suite:
-
-     !(entry->schedule == svn_wc_schedule_add
-       || entry->schedule == svn_wc_schedule_replace
-       || (entry->schedule == svn_wc_schedule_normal && entry->copied)))
-
-  */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_SCHEDULE
-      && cur_entry->schedule == svn_wc_schedule_delete)
-    {
-      cur_entry->copied = FALSE;
-      cur_entry->copyfrom_rev = SVN_INVALID_REVNUM;
-      cur_entry->copyfrom_url = NULL;
-    }
-
-  /* working_size is no longer passed to entry_modify()  */
-
-  /* keep_local makes sense only when we are going to delete directory. */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_SCHEDULE
-      && cur_entry->schedule != svn_wc_schedule_delete)
-    {
-      cur_entry->keep_local = FALSE;
-    }
-
-  /* File externals are no longer passed to entry_modify(). */
-
-  return SVN_NO_ERROR;
-}
-
-
-/* Our general purpose intelligence module for handling a scheduling change
-   to a single entry.
-
-   Given an ENTRY with name NAME, examine the caller's requested scheduling
-    change and the current state of the entry and its directory entry
-   THIS_DIR_ENTRY, which can be equal to ENTRY.
-
-   Determine the final schedule for the entry based on NEW_SCHEDULE and the
-   entries.
-
-   The output can be:
-    * *SKIP_SCHEDULE_CHANGE set to true, when no schedule change is necessary.
-    * Or a schedule change.
-
-   In all these cases *RESULT_SCHEDULE contains the new schedule value.
- */
-static svn_error_t *
-fold_scheduling(svn_boolean_t *skip_schedule_change,
-                svn_wc_schedule_t *result_schedule,
-                const svn_wc_entry_t *this_dir_entry,
-                const svn_wc_entry_t *entry,
-                svn_wc_schedule_t new_schedule,
-                const char *name)
-{
-  SVN_ERR_ASSERT(this_dir_entry);
-  SVN_ERR_ASSERT(new_schedule != svn_wc_schedule_replace);
-
-  *skip_schedule_change = FALSE;
-  *result_schedule = new_schedule;
-
-  /* The only operation valid on an item not already in revision
-     control is addition. */
-  if (entry == NULL)
-    {
-      if (new_schedule == svn_wc_schedule_add)
-        return SVN_NO_ERROR;
-
-      return svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
-                               _("'%s' is not under version control"),
-                               name);
-    }
-
-  /* At this point, we know the following things:
-
-     1. There is already an entry for this item in the entries file
-        whose existence is either _normal or _added (or about to
-        become such), which for our purposes mean the same thing.
-
-     2. We have been asked to merge in a state change, not to
-        explicitly set the state.  */
-
-  /* Here are some cases that are parent-directory sensitive.
-     Basically, we make sure that we are not allowing versioned
-     resources to just sorta dangle below directories marked for
-     deletion. */
-  if ((entry != this_dir_entry)
-      && (this_dir_entry->schedule == svn_wc_schedule_delete))
-    {
-      if (new_schedule == svn_wc_schedule_add)
-        return
-          svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
-                            _("Can't add '%s' to deleted directory; "
-                              "try undeleting its parent directory first"),
-                            name);
-    }
-
-  if (entry->absent && (new_schedule == svn_wc_schedule_add))
-    {
-      return svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
-                               _("'%s' is marked as absent, so it cannot "
-                                 "be scheduled for addition"),
-                               name);
-    }
-
-  if (entry->schedule == svn_wc_schedule_normal
-      && new_schedule == svn_wc_schedule_add
-      && !entry->deleted)
-    {
-      /* You can't add something that's already been added to
-         revision control... unless it's got a 'deleted' state */
-      return svn_error_createf(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
-                               _("Entry '%s' is already under version "
-                                 "control"),
-                               name);
-    }
-
-  if (entry->schedule == svn_wc_schedule_normal)
-    {
-      if (new_schedule == svn_wc_schedule_normal)
-        {
-          /* No-op case.  */
-          *skip_schedule_change = TRUE;
-        }
-    }
-  else if (entry->schedule == svn_wc_schedule_add)
-    {
-      if (new_schedule == svn_wc_schedule_normal
-          || new_schedule == svn_wc_schedule_add)
-        {
-          /* These are both no-op cases.  Normal is obvious, as is add.
-
-             ### Neither case is obvious: above, we throw an error if
-             ### already versioned, so why not here too?
-          */
-          *skip_schedule_change = TRUE;
-        }
-      else if (new_schedule == svn_wc_schedule_delete)
-        {
-          /* This is deleting a node added over the top of a not-present
-             (DELETED=true) node. Return it to the not-present state.  */
-          /* ### not trying to delete the directory, and this is a
-             ### not-present node. (otherwise, caller handles this case)  */
-          SVN_ERR_ASSERT(entry != this_dir_entry);
-          SVN_ERR_ASSERT(entry->deleted);
-
-          *result_schedule = svn_wc_schedule_normal;
-        }
-    }
-  else if (entry->schedule == svn_wc_schedule_delete)
-    {
-      if (new_schedule == svn_wc_schedule_normal)
-        {
-          /* Reverting a delete results in normal */
-        }
-      else if (new_schedule == svn_wc_schedule_delete)
-        {
-          /* This is a no-op case  */
-          *skip_schedule_change = TRUE;
-        }
-      else if (new_schedule == svn_wc_schedule_add)
-        {
-          /* Re-adding an entry marked for deletion?  This is really a
-             replace operation. */
-          *result_schedule = svn_wc_schedule_replace;
-        }
-    }
-  else
-    {
-      /* Only possible state left.  */
-      SVN_ERR_ASSERT(entry->schedule == svn_wc_schedule_replace);
-
-      if (new_schedule == svn_wc_schedule_normal)
-        {
-          /* Reverting replacements results in normal  */
-        }
-      else if (new_schedule == svn_wc_schedule_add)
-        {
-          /* Adding a to-be-replaced entry breaks down to ((delete +
-             add) + add) which might deserve a warning, but we'll just
-             no-op it. */
-          *skip_schedule_change = TRUE;
-        }
-      else if (new_schedule == svn_wc_schedule_delete)
-        {
-          /* Deleting a to-be-replaced entry breaks down to ((delete +
-             add) + delete) which resolves to a flat deletion. */
-          *result_schedule = svn_wc_schedule_delete;
-        }
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-
-static svn_error_t *
-entry_modify(svn_wc__db_t *db,
-             const char *local_abspath,
-             svn_node_kind_t kind,
-             svn_boolean_t parent_stub,
-             const svn_wc_entry_t *entry_mods,
-             int modify_flags,
-             apr_pool_t *scratch_pool)
-{
-  apr_pool_t *subpool = svn_pool_create(scratch_pool);
-  svn_error_t *err;
-  svn_wc_adm_access_t *adm_access;
-  const char *adm_abspath;
-  const char *name;
-  const svn_wc_entry_t *parent_entry;
-  svn_wc_entry_t *cur_entry;
-  svn_wc_schedule_t new_schedule;
-
-  SVN_ERR_ASSERT(entry_mods);
-
-  SVN_ERR(get_entry_access_info(&adm_abspath, &name, db, local_abspath,
-                                kind, parent_stub, subpool, subpool));
-
-  /* Load ADM_ABSPATH's whole entries file:
-     Is there an existing access baton for this path?  */
-  adm_access = svn_wc__adm_retrieve_internal2(db, adm_abspath, subpool);
-  if (adm_access != NULL)
-    {
-      /* Are we allowed to write to this admin area?  */
-      SVN_ERR(svn_wc__write_check(db, svn_wc__adm_access_abspath(adm_access),
-                                  subpool));
-
-      /* Zap any cached entries. We're about to change them.  */
-      svn_wc__adm_access_set_entries(adm_access, NULL);
-    }
-  /* ### else: should we have some kind of write check here?  */
-
-  /* Cast our non-const CUR_ENTRY appropriately. It will be allocated for
-     us in SUB_POOL, so we actually know it is modifiable.  */
-  SVN_ERR(read_entry_pair(&parent_entry, (const svn_wc_entry_t **)&cur_entry,
-                          db, adm_abspath, name, subpool, subpool));
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_SCHEDULE)
-    {
-      new_schedule = entry_mods->schedule;
-
-      /* We may just want to force the scheduling change in. Otherwise,
-         call our special function to fold the change in.  */
-      if (!(modify_flags & SVN_WC__ENTRY_MODIFY_FORCE))
-        {
-          svn_boolean_t skip_schedule_change;
-
-          /* ### adm_ops.c is the only code that attempts to transition to
-             ### schedule_replace, but it uses FORCE.  */
-          SVN_ERR_ASSERT(entry_mods->schedule != svn_wc_schedule_replace);
-
-          /* If we are deleting a node that has been added, then simply
-             remove the entry. Do NOT do this for an add over a not-present
-             BASE node (the DELETED flag).  */
-          if (entry_mods->schedule == svn_wc_schedule_delete
-              && cur_entry != NULL
-              && cur_entry->schedule == svn_wc_schedule_add
-              && !cur_entry->deleted)
-            {
-              SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
-                                                      subpool));
-              svn_pool_destroy(subpool);
-              return SVN_NO_ERROR;
-            }
-
-          /* If scheduling changes were made, we have a special routine to
-             manage those modifications. */
-          SVN_ERR(fold_scheduling(&skip_schedule_change,
-                                  &new_schedule,
-                                  parent_entry,
-                                  cur_entry,
-                                  entry_mods->schedule,
-                                  name));
-
-          if (skip_schedule_change)
-            modify_flags &= ~SVN_WC__ENTRY_MODIFY_SCHEDULE;
-        }
-    }
-
-  /* Yay! Our "modify" function can actually "create". Bleah.  */
-  if (cur_entry == NULL)
-    cur_entry = alloc_entry(subpool);
-
-  /* Fold in the changes, and write them out.  */
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_SCHEDULE)
-    cur_entry->schedule = new_schedule;
-  SVN_ERR(fold_entry(cur_entry, name, modify_flags, entry_mods, parent_entry,
-                     subpool));
-
-  err = write_one_entry(db, adm_abspath,
-                        parent_entry,
-                        cur_entry,
-                        subpool);
-
-  svn_pool_destroy(subpool); /* Close wc.db handles */
-
-  return svn_error_return(err);
-}
-
-
-svn_error_t *
-svn_wc__entry_modify(svn_wc__db_t *db,
-                     const char *local_abspath,
-                     svn_node_kind_t kind,
-                     const svn_wc_entry_t *entry,
-                     int modify_flags,
-                     apr_pool_t *scratch_pool)
-{
-  return svn_error_return(entry_modify(db, local_abspath, kind, FALSE,
-                                       entry, modify_flags, scratch_pool));
-}
-
-
-svn_error_t *
-svn_wc__entry_modify_stub(svn_wc__db_t *db,
-                          const char *local_abspath,
-                          const svn_wc_entry_t *entry,
-                          int modify_flags,
-                          apr_pool_t *scratch_pool)
-{
-  SVN_ERR_ASSERT((modify_flags & ~(
-                    /* from adm_ops.c  */
-                    SVN_WC__ENTRY_MODIFY_SCHEDULE
-                    | SVN_WC__ENTRY_MODIFY_KIND
-                    | SVN_WC__ENTRY_MODIFY_REVISION
-                    | SVN_WC__ENTRY_MODIFY_COPYFROM_URL
-                    | SVN_WC__ENTRY_MODIFY_COPYFROM_REV
-                    | SVN_WC__ENTRY_MODIFY_COPIED
-                    | SVN_WC__ENTRY_MODIFY_CHECKSUM
-
-                    /* from entries.c  */
-                    | SVN_WC__ENTRY_MODIFY_URL
-                    | SVN_WC__ENTRY_MODIFY_REVISION
-
-                    | SVN_WC__ENTRY_MODIFY_DELETED
-                    | SVN_WC__ENTRY_MODIFY_SCHEDULE
-                    | SVN_WC__ENTRY_MODIFY_FORCE
-
-                    /* from update_editor.c  */
-                    | SVN_WC__ENTRY_MODIFY_KIND
-                    | SVN_WC__ENTRY_MODIFY_DELETED
-                    | SVN_WC__ENTRY_MODIFY_ABSENT
-                    | SVN_WC__ENTRY_MODIFY_SCHEDULE
-                    | SVN_WC__ENTRY_MODIFY_FORCE
-
-                    /* from workqueue.c  */
-                    | SVN_WC__ENTRY_MODIFY_COPIED
-                    | SVN_WC__ENTRY_MODIFY_COPYFROM_URL
-                    | SVN_WC__ENTRY_MODIFY_COPYFROM_REV
-                    | SVN_WC__ENTRY_MODIFY_SCHEDULE
-                                   )) == 0);
-  return svn_error_return(entry_modify(db, local_abspath,
-                                       svn_node_dir, TRUE,
-                                       entry, modify_flags, scratch_pool));
-}
-
 
 svn_wc_entry_t *
 svn_wc_entry_dup(const svn_wc_entry_t *entry, apr_pool_t *pool)
@@ -3107,76 +2354,6 @@ svn_wc_entry_dup(const svn_wc_entry_t *e
 }
 
 
-svn_error_t *
-svn_wc__tweak_entry(svn_wc__db_t *db,
-                    const char *local_abspath,
-                    svn_node_kind_t kind,
-                    svn_boolean_t parent_stub,
-                    const char *new_url,
-                    svn_revnum_t new_rev,
-                    svn_boolean_t allow_removal,
-                    apr_pool_t *scratch_pool)
-{
-  const svn_wc_entry_t *entry;
-  svn_wc_entry_t tmp_entry;
-  int modify_flags = 0;
-
-  SVN_ERR(svn_wc__get_entry(&entry, db, local_abspath, FALSE, kind,
-                            parent_stub, scratch_pool, scratch_pool));
-
-  if (new_url != NULL
-      && (! entry->url || strcmp(new_url, entry->url)))
-    {
-      modify_flags |= SVN_WC__ENTRY_MODIFY_URL;
-      tmp_entry.url = new_url;
-    }
-
-  if ((SVN_IS_VALID_REVNUM(new_rev))
-      && (entry->schedule != svn_wc_schedule_add)
-      && (entry->schedule != svn_wc_schedule_replace)
-      && (entry->copied != TRUE)
-      && (entry->revision != new_rev))
-    {
-      modify_flags |= SVN_WC__ENTRY_MODIFY_REVISION;
-      tmp_entry.revision = new_rev;
-    }
-
-  /* As long as this function is only called as a helper to
-     svn_wc__do_update_cleanup, then it's okay to remove any entry
-     under certain circumstances:
-
-     If the entry is still marked 'deleted', then the server did not
-     re-add it.  So it's really gone in this revision, thus we remove
-     the entry.
-
-     If the entry is still marked 'absent' and yet is not the same
-     revision as new_rev, then the server did not re-add it, nor
-     re-absent it, so we can remove the entry.
-
-     ### This function cannot always determine whether removal is
-     ### appropriate, hence the ALLOW_REMOVAL flag.  It's all a bit of a
-     ### mess. */
-  if (allow_removal
-      && (entry->deleted || (entry->absent && entry->revision != new_rev)))
-    {
-      SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
-                                              scratch_pool));
-    }
-  else if (modify_flags)
-    {
-      if (entry->kind == svn_node_dir && parent_stub)
-        SVN_ERR(svn_wc__entry_modify_stub(db, local_abspath,
-                                          &tmp_entry, modify_flags,
-                                          scratch_pool));
-      else
-        SVN_ERR(svn_wc__entry_modify(db, local_abspath, entry->kind,
-                                     &tmp_entry, modify_flags, scratch_pool));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
 /*** Generic Entry Walker */
 
 /* A recursive entry-walker, helper for svn_wc_walk_entries3().
@@ -3415,29 +2592,39 @@ svn_wc__temp_mark_missing_not_present(co
 {
   svn_wc__db_status_t status;
   svn_wc__db_kind_t kind;
+  const char *repos_relpath, *repos_root_url, *repos_uuid;
+  svn_revnum_t revision;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR(svn_wc__db_read_info(&status, &kind,
+  SVN_ERR(svn_wc__db_read_info(&status, &kind, &revision, &repos_relpath,
+                               &repos_root_url, &repos_uuid, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL,
+                               NULL, NULL,
                                wc_ctx->db, local_abspath,
                                scratch_pool, scratch_pool));
   if (kind == svn_wc__db_kind_dir
       && status == svn_wc__db_status_obstructed_delete)
     {
-      svn_wc_entry_t tmp_entry;
+      if (!repos_relpath)
+        SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+                                           &repos_uuid,
+                                           wc_ctx->db, local_abspath,
+                                           scratch_pool, scratch_pool));
+
+      SVN_ERR(svn_wc__db_temp_op_remove_entry(wc_ctx->db, local_abspath,
+                                              scratch_pool));
 
-      tmp_entry.deleted = TRUE;
-      tmp_entry.schedule = svn_wc_schedule_normal;
+      if (!SVN_IS_VALID_REVNUM(revision))
+        revision = 0; /* Just make one up */
+
+      SVN_ERR(svn_wc__db_base_add_absent_node(wc_ctx->db, local_abspath,
+                                              repos_relpath, repos_root_url,
+                                              repos_uuid, revision,
+                                              svn_wc__db_kind_dir,
+                                              svn_wc__db_status_not_present,
+                                              NULL, NULL, scratch_pool));
 
-      SVN_ERR(svn_wc__entry_modify_stub(wc_ctx->db, local_abspath,
-                                        &tmp_entry,
-                                        (SVN_WC__ENTRY_MODIFY_DELETED
-                                         | SVN_WC__ENTRY_MODIFY_SCHEDULE
-                                         | SVN_WC__ENTRY_MODIFY_FORCE),
-                                        scratch_pool));
       return SVN_NO_ERROR;
     }
 
@@ -3446,23 +2633,3 @@ svn_wc__temp_mark_missing_not_present(co
                              "path is marked 'missing'"),
                            svn_dirent_local_style(local_abspath, scratch_pool));
 }
-
-svn_error_t *
-svn_wc_mark_missing_deleted(const char *path,
-                            svn_wc_adm_access_t *parent,
-                            apr_pool_t *pool)
-{
-  const char *local_abspath;
-  svn_wc_context_t *wc_ctx;
-
-  SVN_ERR(svn_wc__context_create_with_db(&wc_ctx, NULL,
-                                         svn_wc__adm_get_db(parent), pool));
-
-  SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
-
-  SVN_ERR(svn_wc__temp_mark_missing_not_present(local_abspath, wc_ctx, pool));
-
-  SVN_ERR(svn_wc_context_destroy(wc_ctx));
-
-  return SVN_NO_ERROR;
-}

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.h?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/entries.h Tue Aug 10 22:07:24 2010
@@ -37,120 +37,6 @@
 extern "C" {
 #endif /* __cplusplus */
 
-
-/* The names of the fields used for storing entries' information.
-   Used for the names of the XML attributes in XML entries files
-   (format 6 and below), for the names of attributes in wc logs,
-   and for error reporting when reading a non-XML entries file.
-   ### If you add or remove items here, you probably want to make sure
-   to do the same for the SVN_WC__ENTRY_MODIFY_* #defines as well. */
-#define SVN_WC__ENTRY_ATTR_CONFLICT_OLD       "conflict-old" /* saved old file */
-#define SVN_WC__ENTRY_ATTR_CONFLICT_NEW       "conflict-new" /* saved new file */
-#define SVN_WC__ENTRY_ATTR_CONFLICT_WRK       "conflict-wrk" /* saved wrk file */
-#define SVN_WC__ENTRY_ATTR_PREJFILE           "prop-reject-file"
-
-
-/* Set *NEW_ENTRY to a new entry, taking attributes from ATTS, whose
-   keys and values are both char *.  Allocate the entry and copy
-   attributes into POOL as needed.
-
-   Set MODIFY_FLAGS to reflect the fields that were present in ATTS. */
-svn_error_t *svn_wc__atts_to_entry(svn_wc_entry_t **new_entry,
-                                   int *modify_flags,
-                                   apr_hash_t *atts,
-                                   apr_pool_t *pool);
-
-
-/* The MODIFY_FLAGS that tell svn_wc__entry_modify which parameters to
-   pay attention to.  ### These should track the changes made to the
-   SVN_WC__ENTRY_ATTR_* #defines! */
-#define SVN_WC__ENTRY_MODIFY_REVISION           0x00000001
-#define SVN_WC__ENTRY_MODIFY_URL                0x00000002
-#define SVN_WC__ENTRY_MODIFY_KIND               0x00000004
-/* ### gap  */
-#define SVN_WC__ENTRY_MODIFY_CHECKSUM           0x00000010
-#define SVN_WC__ENTRY_MODIFY_SCHEDULE           0x00000020
-#define SVN_WC__ENTRY_MODIFY_COPIED             0x00000040
-#define SVN_WC__ENTRY_MODIFY_DELETED            0x00000080
-#define SVN_WC__ENTRY_MODIFY_COPYFROM_URL       0x00000100
-#define SVN_WC__ENTRY_MODIFY_COPYFROM_REV       0x00000200
-#define SVN_WC__ENTRY_MODIFY_CONFLICT_OLD       0x00000400
-#define SVN_WC__ENTRY_MODIFY_CONFLICT_NEW       0x00000800
-#define SVN_WC__ENTRY_MODIFY_CONFLICT_WRK       0x00001000
-#define SVN_WC__ENTRY_MODIFY_PREJFILE           0x00002000
-#define SVN_WC__ENTRY_MODIFY_ABSENT             0x00004000
-/* ### gap  */
-
-/* ...ORed together with this to mean: just set the schedule to the new
-   value, instead of treating the new value as a change of state to be
-   merged with the current schedule. */
-#define SVN_WC__ENTRY_MODIFY_FORCE              0x00020000
-
-
-/* Modify the entry for LOCAL_ABSPATH in DB by folding in
-   ("merging") changes, and sync those changes to disk.  New values
-   for the entry are pulled from their respective fields in ENTRY, and
-   MODIFY_FLAGS is a bitmask to specify which of those fields to pay
-   attention to, formed from the values SVN_WC__ENTRY_MODIFY_....
-
-   ### Old doc: "ADM_ACCESS must hold a write lock."
-
-   If LOCAL_ABSPATH specifies a directory, its full entry will be modified.
-   To modify its "parent stub" entry, use svn_wc__entry_modify_stub().
-
-   "Folding in" a change means, in most cases, simply replacing the field
-   with the new value. However, for the "schedule" field, unless
-   MODIFY_FLAGS includes SVN_WC__ENTRY_MODIFY_FORCE (in which case just take
-   the new schedule from ENTRY), it means to determine the schedule that the
-   entry should end up with if the "schedule" value from ENTRY represents a
-   change/add/delete/replace being made to the
-     ### base / working / base and working version(s) ?
-   of the node.
-
-   Perform all allocations in SCRATCH_POOL.
-*/
-svn_error_t *
-svn_wc__entry_modify(svn_wc__db_t *db,
-                     const char *local_abspath,
-                     svn_node_kind_t kind,
-                     const svn_wc_entry_t *entry,
-                     int modify_flags,
-                     apr_pool_t *scratch_pool);
-
-
-/* Like svn_wc__entry_modify(), but modifies the "parent stub".  */
-svn_error_t *
-svn_wc__entry_modify_stub(svn_wc__db_t *db,
-                          const char *local_abspath,
-                          const svn_wc_entry_t *entry,
-                          int modify_flags,
-                          apr_pool_t *scratch_pool);
-
-
-/* Tweak the information for LOCAL_ABSPATH in DB.  If NEW_URL is non-null,
- * make this the entry's new url.  If NEW_REV is valid, make this the
- * entry's working revision.
- *
- * If ALLOW_REMOVAL is TRUE the tweaks might cause the entry for
- * LOCAL_ABSPATH to be removed from the WC; if ALLOW_REMOVAL is FALSE this
- * will not happen.
- *
- * THIS_DIR should be true if the LOCAL_ABSPATH refers to a directory, and
- * the information to be edited is not in the stub entry.
- *
- * (Intended as a helper to svn_wc__do_update_cleanup, which see.)
- */
-svn_error_t *
-svn_wc__tweak_entry(svn_wc__db_t *db,
-                    const char *local_abspath,
-                    svn_node_kind_t kind,
-                    svn_boolean_t parent_stub,
-                    const char *new_url,
-                    svn_revnum_t new_rev,
-                    svn_boolean_t allow_removal,
-                    apr_pool_t *scratch_pool);
-
-
 /** Get an ENTRY for the given LOCAL_ABSPATH.
  *
  * This API does not require an access baton, just a wc_db handle (DB).
@@ -199,7 +85,6 @@ svn_wc__get_entry(const svn_wc_entry_t *
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool);
 
-
 /* Is ENTRY in a 'hidden' state in the sense of the 'show_hidden'
  * switches on svn_wc_entries_read(), svn_wc_walk_entries*(), etc.? */
 svn_error_t *
@@ -223,15 +108,6 @@ svn_wc__write_upgraded_entries(svn_wc__d
                                apr_hash_t *entries,
                                apr_pool_t *scratch_pool);
 
-
-/* ### return a flag corresponding to the classic "DELETED" concept.  */
-svn_error_t *
-svn_wc__node_is_deleted(svn_boolean_t *deleted,
-                        svn_wc__db_t *db,
-                        const char *local_abspath,
-                        apr_pool_t *scratch_pool);
-
-
 /* Parse a file external specification in the NULL terminated STR and
    place the path in PATH_RESULT, the peg revision in PEG_REV_RESULT
    and revision number in REV_RESULT.  STR may be NULL, in which case

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/lock.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/lock.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/lock.c Tue Aug 10 22:07:24 2010
@@ -36,7 +36,6 @@
 #include "lock.h"
 #include "props.h"
 #include "log.h"
-#include "entries.h"
 #include "wc_db.h"
 
 #include "svn_private_config.h"
@@ -310,7 +309,14 @@ adm_access_alloc(svn_wc_adm_access_t **a
 
   if (write_lock)
     {
-      SVN_ERR(svn_wc__db_wclock_set(db, lock->abspath, 0, scratch_pool));
+      svn_boolean_t owns_lock;
+
+      /* If the db already owns a lock, we can't add an extra lock record */
+      SVN_ERR(svn_wc__db_temp_own_lock(&owns_lock, db, path, scratch_pool));
+
+      if (!owns_lock)
+        SVN_ERR(svn_wc__db_wclock_set(db, lock->abspath, 0, scratch_pool));
+
       SVN_ERR(svn_wc__db_temp_mark_locked(db, lock->abspath, scratch_pool));
     }
 
@@ -1044,7 +1050,7 @@ child_is_disjoint(svn_boolean_t *disjoin
   svn_boolean_t found_in_parent = FALSE;
   int i;
 
-  svn_dirent_split(local_abspath, &parent_abspath, &base, scratch_pool);
+  svn_dirent_split(&parent_abspath, &base, local_abspath, scratch_pool);
 
   /* Check if the parent directory knows about this node */
   err = svn_wc__db_read_children(&children, db, parent_abspath, scratch_pool,
@@ -1564,7 +1570,7 @@ svn_wc__acquire_write_lock(const char **
       parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
       err = svn_wc__db_read_kind(&parent_kind, wc_ctx->db, parent_abspath, TRUE,
                                  scratch_pool);
-      if (err && err->apr_err == SVN_ERR_WC_NOT_DIRECTORY)
+      if (err && SVN_WC__ERR_IS_NOT_CURRENT_WC(err))
         {
           svn_error_clear(err);
           parent_kind = svn_wc__db_kind_unknown;
@@ -1732,8 +1738,10 @@ svn_wc__path_switched(svn_boolean_t *swi
                       const char *local_abspath,
                       apr_pool_t *scratch_pool)
 {
-  return svn_error_return(child_is_disjoint(switched, wc_ctx->db,
-                                            local_abspath, scratch_pool));
+  svn_boolean_t wc_root;
+
+  return svn_wc__check_wc_root(&wc_root, NULL, switched, wc_ctx->db,
+                               local_abspath, scratch_pool);
 }
 
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.c Tue Aug 10 22:07:24 2010
@@ -43,7 +43,6 @@
 #include "log.h"
 #include "props.h"
 #include "adm_files.h"
-#include "entries.h"
 #include "lock.h"
 #include "translate.h"
 #include "tree_conflicts.h"
@@ -70,13 +69,6 @@
 
 /** Log actions. **/
 
-/* Set some attributes on SVN_WC__LOG_ATTR_NAME's entry.  Unmentioned
-   attributes are unaffected. */
-#define SVN_WC__LOG_MODIFY_ENTRY        "modify-entry"
-
-/* Delete lock related fields from the entry SVN_WC__LOG_ATTR_NAME. */
-#define SVN_WC__LOG_DELETE_LOCK         "delete-lock"
-
 /* Delete the entry SVN_WC__LOG_ATTR_NAME. */
 #define SVN_WC__LOG_DELETE_ENTRY        "delete-entry"
 #define SVN_WC__LOG_ATTR_REVISION       "revision"
@@ -247,50 +239,6 @@ log_do_file_timestamp(struct log_runner 
 }
 
 
-/* */
-static svn_error_t *
-log_do_modify_entry(struct log_runner *loggy,
-                    const char *name,
-                    const char **atts)
-{
-  apr_hash_t *ah = svn_xml_make_att_hash(atts, loggy->pool);
-  const char *local_abspath;
-  svn_wc_entry_t *entry;
-  int modify_flags;
-
-  local_abspath = svn_dirent_join(loggy->adm_abspath, name, loggy->pool);
-
-  /* Convert the attributes into an entry structure. */
-  SVN_ERR(svn_wc__atts_to_entry(&entry, &modify_flags, ah, loggy->pool));
-
-  /* ### this function never needs to modify a parent stub.
-     ### NOTE: this call to entry_modify MAY create a new node.  */
-  return svn_error_return(svn_wc__entry_modify(loggy->db, local_abspath,
-                                               svn_node_unknown,
-                                               entry, modify_flags,
-                                               loggy->pool));
-}
-
-/* */
-static svn_error_t *
-log_do_delete_lock(struct log_runner *loggy,
-                   const char *name)
-{
-  const char *local_abspath;
-  svn_error_t *err;
-
-  local_abspath = svn_dirent_join(loggy->adm_abspath, name, loggy->pool);
-
-  err = svn_wc__db_lock_remove(loggy->db, local_abspath, loggy->pool);
-  if (err)
-    return svn_error_createf(SVN_ERR_WC_BAD_ADM_LOG, err,
-                             _("Error removing lock from entry for '%s'"),
-                             name);
-
-  return SVN_NO_ERROR;
-}
-
-
 /* Ben sez:  this log command is (at the moment) only executed by the
    update editor.  It attempts to forcefully remove working data. */
 /* Delete a node from version control, and from disk if unmodified.
@@ -465,13 +413,7 @@ start_handler(void *userData, const char
 #endif
 
   /* Dispatch. */
-  if (strcmp(eltname, SVN_WC__LOG_MODIFY_ENTRY) == 0) {
-    err = log_do_modify_entry(loggy, name, atts);
-  }
-  else if (strcmp(eltname, SVN_WC__LOG_DELETE_LOCK) == 0) {
-    err = log_do_delete_lock(loggy, name);
-  }
-  else if (strcmp(eltname, SVN_WC__LOG_DELETE_ENTRY) == 0) {
+  if (strcmp(eltname, SVN_WC__LOG_DELETE_ENTRY) == 0) {
     const char *attr;
     svn_revnum_t revision;
     svn_node_kind_t kind;
@@ -670,100 +612,6 @@ svn_wc__loggy_delete_entry(svn_skel_t **
 }
 
 svn_error_t *
-svn_wc__loggy_delete_lock(svn_skel_t **work_item,
-                          svn_wc__db_t *db,
-                          const char *adm_abspath,
-                          const char *local_abspath,
-                          apr_pool_t *result_pool)
-{
-  const char *loggy_path1;
-  svn_stringbuf_t *log_accum = NULL;
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-
-  SVN_ERR(loggy_path(&loggy_path1, local_abspath, adm_abspath, result_pool));
-  svn_xml_make_open_tag(&log_accum, result_pool, svn_xml_self_closing,
-                        SVN_WC__LOG_DELETE_LOCK,
-                        SVN_WC__LOG_ATTR_NAME, loggy_path1,
-                        NULL);
-
-  return svn_error_return(svn_wc__wq_build_loggy(work_item,
-                                                 db, adm_abspath, log_accum,
-                                                 result_pool));
-}
-
-
-svn_error_t *
-svn_wc__loggy_entry_modify(svn_skel_t **work_item,
-                           svn_wc__db_t *db,
-                           const char *adm_abspath,
-                           const char *local_abspath,
-                           const svn_wc_entry_t *entry,
-                           apr_uint64_t modify_flags,
-                           apr_pool_t *result_pool)
-{
-  svn_stringbuf_t *log_accum = NULL;
-  const char *loggy_path1;
-  apr_hash_t *prop_hash = apr_hash_make(result_pool);
-
-  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
-  SVN_ERR_ASSERT(modify_flags != 0);
-
-  /* ### this code has a limited set of modifications. enforce it.  */
-  SVN_ERR_ASSERT((modify_flags & ~(0
-                    /* from props.c  */
-                    | SVN_WC__ENTRY_MODIFY_PREJFILE
-
-                    /* from merge.c  */
-                    | SVN_WC__ENTRY_MODIFY_CONFLICT_OLD
-                    | SVN_WC__ENTRY_MODIFY_CONFLICT_NEW
-                    | SVN_WC__ENTRY_MODIFY_CONFLICT_WRK)) == 0);
-
-#define ADD_ENTRY_ATTR(attr_flag, attr_name, value) \
-   if (modify_flags & (attr_flag)) \
-     apr_hash_set(prop_hash, (attr_name), APR_HASH_KEY_STRING, value)
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CONFLICT_OLD)
-    SVN_ERR_ASSERT(entry->conflict_old != NULL);
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CONFLICT_OLD,
-                 SVN_WC__ENTRY_ATTR_CONFLICT_OLD,
-                 entry->conflict_old);
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_CONFLICT_NEW)
-    SVN_ERR_ASSERT(entry->conflict_new != NULL);
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CONFLICT_NEW,
-                 SVN_WC__ENTRY_ATTR_CONFLICT_NEW,
-                 entry->conflict_new);
-
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_CONFLICT_WRK,
-                 SVN_WC__ENTRY_ATTR_CONFLICT_WRK,
-                 entry->conflict_wrk ? entry->conflict_wrk : "");
-
-  if (modify_flags & SVN_WC__ENTRY_MODIFY_PREJFILE)
-    SVN_ERR_ASSERT(entry->prejfile != NULL);
-  ADD_ENTRY_ATTR(SVN_WC__ENTRY_MODIFY_PREJFILE,
-                 SVN_WC__ENTRY_ATTR_PREJFILE,
-                 entry->prejfile);
-
-#undef ADD_ENTRY_ATTR
-
-  SVN_ERR_ASSERT(apr_hash_count(prop_hash) != 0);
-
-  SVN_ERR(loggy_path(&loggy_path1, local_abspath, adm_abspath, result_pool));
-  apr_hash_set(prop_hash, SVN_WC__LOG_ATTR_NAME,
-               APR_HASH_KEY_STRING, loggy_path1);
-
-  svn_xml_make_open_tag_hash(&log_accum, result_pool,
-                             svn_xml_self_closing,
-                             SVN_WC__LOG_MODIFY_ENTRY,
-                             prop_hash);
-  return svn_error_return(svn_wc__wq_build_loggy(work_item,
-                                                 db, adm_abspath, log_accum,
-                                                 result_pool));
-}
-
-
-svn_error_t *
 svn_wc__loggy_move(svn_skel_t **work_item,
                    svn_wc__db_t *db,
                    const char *adm_abspath,
@@ -953,11 +801,20 @@ cleanup_internal(svn_wc__db_t *db,
         }
     }
 
+#ifndef SINGLE_DB
+  /* Purge the DAV props at and under ADM_ABSPATH. */
+  /* ### in single-db mode, we need do this purge at the top-level only. */
+  SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, adm_abspath, iterpool));
+#endif
+
   /* Cleanup the tmp area of the admin subdir, if running the log has not
      removed it!  The logs have been run, so anything left here has no hope
      of being useful. */
   SVN_ERR(svn_wc__adm_cleanup_tmp_area(db, adm_abspath, iterpool));
 
+  /* Remove unreferenced pristine texts */
+  SVN_ERR(svn_wc__db_pristine_cleanup(db, adm_abspath, iterpool));
+
   /* All done, toss the lock */
   SVN_ERR(svn_wc__db_wclock_remove(db, adm_abspath, iterpool));
 
@@ -990,6 +847,12 @@ svn_wc_cleanup3(svn_wc_context_t *wc_ctx
   SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton,
                            scratch_pool));
 
+#ifdef SINGLE_DB
+  /* Purge the DAV props at and under LOCAL_ABSPATH. */
+  /* ### in single-db mode, we need do this purge at the top-level only. */
+  SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, adm_abspath, iterpool));
+#endif
+
   /* We're done with this DB, so proactively close it.  */
   SVN_ERR(svn_wc__db_close(db));
 

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.h?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/log.h Tue Aug 10 22:07:24 2010
@@ -39,15 +39,21 @@ extern "C" {
 #endif /* __cplusplus */
 
 
-/* Each path argument to the svn_wc__loggy_* functions in this section can
-   be either absolute or relative to the adm_abspath argument.
+/* Common arguments:
+
+   Each svn_wc__loggy_* function in this section takes an ADM_ABSPATH
+   argument which is the working copy directory inside which the operation
+   is to be performed.  Any other *_ABSPATH arguments must be paths inside
+   ADM_ABSPATH (or equal to it, where that makes sense).
 */
 
 
-/* Insert into DB a work queue instruction to generate a translated
-   file from SRC to DST with translation settings from VERSIONED.
-   ADM_ABSPATH is the absolute path for the admin directory for PATH.
-   DST and SRC and VERSIONED are relative to ADM_ABSPATH.  */
+/* Set *WORK_ITEM to a work queue instruction to generate a translated
+   file from SRC_ABSPATH to DST_ABSPATH with translation settings from
+   VERSIONED_ABSPATH.
+
+   ADM_ABSPATH is described above.
+*/
 svn_error_t *
 svn_wc__loggy_translated_file(svn_skel_t **work_item,
                               svn_wc__db_t *db,
@@ -57,13 +63,14 @@ svn_wc__loggy_translated_file(svn_skel_t
                               const char *versioned_abspath,
                               apr_pool_t *result_pool);
 
-/* Insert into DB a work queue instruction to delete the entry
-   associated with PATH from the entries file.
-   ADM_ABSPATH is the absolute path for the access baton for PATH.
+/* Set *WORK_ITEM to a work queue instruction to delete the entry
+   associated with LOCAL_ABSPATH from the entries file.
 
-   ### REVISION and KIND
+   REVISION and KIND are used to insert a "not present" base node row if
+   REVISION is not SVN_INVALID_REVNUM: see svn_wc__db_base_add_absent_node()
+   for details.
 
-   Use SCRATCH_POOL for temporary allocations.
+   ADM_ABSPATH is described above.
 */
 svn_error_t *
 svn_wc__loggy_delete_entry(svn_skel_t **work_item,
@@ -74,52 +81,17 @@ svn_wc__loggy_delete_entry(svn_skel_t **
                            svn_wc__db_kind_t kind,
                            apr_pool_t *result_pool);
 
+/* Set *WORK_ITEM to a work queue instruction to move the file SRC_ABSPATH
+   to DST_ABSPATH.
 
-/* Insert into DB a work queue instruction to delete lock related
-   fields from the entry belonging to PATH.
-   ADM_ABSPATH is the absolute path for the access baton for PATH.
-
-   Use SCRATCH_POOL for temporary allocations.
-*/
-svn_error_t *
-svn_wc__loggy_delete_lock(svn_skel_t **work_item,
-                          svn_wc__db_t *db,
-                          const char *adm_abspath,
-                          const char *local_abspath,
-                          apr_pool_t *result_pool);
-
-
-/* Queue operations to modify the entry associated with PATH
-   in ADM_ABSPATH according to the flags specified in MODIFY_FLAGS, based on
-   the values supplied in *ENTRY.
-
-   ADM_ABSPATH is the absolute path for the admin directory for PATH.
-
-   The flags in MODIFY_FLAGS are to be taken from the svn_wc__entry_modify()
-   parameter by the same name.
-
-   Use SCRATCH_POOL for temporary allocations.
-*/
-svn_error_t *
-svn_wc__loggy_entry_modify(svn_skel_t **work_item,
-                           svn_wc__db_t *db,
-                           const char *adm_abspath,
-                           const char *local_abspath,
-                           const svn_wc_entry_t *entry,
-                           apr_uint64_t modify_flags,
-                           apr_pool_t *result_pool);
-
-
-/* Queue instructions to move the file SRC_PATH to DST_PATH.
-
-   The test for existence is made now, not at log run time.
-
-   ADM_ABSPATH is the absolute path for the admin directory for PATH.
-   SRC_PATH and DST_PATH are relative to ADM_ABSPATH.
+   The file SRC_ABSPATH must exist.  The test for existence is made now, not
+   at log run time.
 
    Set *DST_MODIFIED (if DST_MODIFIED isn't NULL) to indicate whether the
    destination path will have been modified after running the log: if either
    the move or the remove will have been carried out.
+
+   ADM_ABSPATH is described above.
 */
 svn_error_t *
 svn_wc__loggy_move(svn_skel_t **work_item,
@@ -130,10 +102,10 @@ svn_wc__loggy_move(svn_skel_t **work_ite
                    apr_pool_t *result_pool);
 
 
-/* Queue instructions to set the timestamp of PATH to
-   the time TIMESTR.
+/* Set *WORK_ITEM to a work queue instruction to set the timestamp of
+   LOCAL_ABSPATH to the time TIMESTR.
 
-   ADM_ABSPATH is the absolute path for the admin directory for PATH.
+   ADM_ABSPATH is described above.
 */
 svn_error_t *
 svn_wc__loggy_set_timestamp(svn_skel_t **work_item,
@@ -143,7 +115,11 @@ svn_wc__loggy_set_timestamp(svn_skel_t *
                             const char *timestr,
                             apr_pool_t *result_pool);
 
-/* */
+/* Set *WORK_ITEM to a work queue instruction to
+   ### ...
+
+   ADM_ABSPATH is described above.
+*/
 svn_error_t *
 svn_wc__loggy_add_tree_conflict(svn_skel_t **work_item,
                                 svn_wc__db_t *db,

Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/merge.c?rev=984234&r1=984233&r2=984234&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/merge.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_wc/merge.c Tue Aug 10 22:07:24 2010
@@ -28,7 +28,6 @@
 #include "svn_pools.h"
 
 #include "wc.h"
-#include "entries.h"
 #include "adm_files.h"
 #include "translate.h"
 #include "log.h"
@@ -297,7 +296,12 @@ maybe_update_target_eols(const char **ne
 }
 
 
-/* Helper for do_text_merge_internal() below. */
+/* Set *TARGET_MARKER, *LEFT_MARKER and *RIGHT_MARKER to strings suitable
+   for delimiting the alternative texts in a text conflict.  Include in each
+   marker a string that may be given by TARGET_LABEL, LEFT_LABEL and
+   RIGHT_LABEL respectively or a default value where any of those are NULL.
+
+   Allocate the results in POOL or statically. */
 static void
 init_conflict_markers(const char **target_marker,
                       const char **left_marker,
@@ -401,28 +405,29 @@ do_text_merge_external(svn_boolean_t *co
   return SVN_NO_ERROR;
 }
 
-/* Return a work item to copy/translate the merge result, obtained during
-   interactive conflict resolution, to the file RESULT_TARGET. The merge
-   result is expected in the same directory as TARGET_ABSPATH, with the same
-   basename as TARGET_ABSPATH, with a ".edited" extension.
+/* Create a new file in the same directory as VERSIONED_ABSPATH, with the
+   same basename as VERSIONED_ABSPATH, with a ".edited" extension, and set
+   *WORK_ITEM to a new work item that will copy and translate from the file
+   SOURCE to that new file.  It will be translated from repository-normal
+   form to working-copy form according to the versioned properties of
+   VERSIONED_ABSPATH that are current when the work item is executed.
 
-   DB should have a write lock for the directory containing RESULT_TARGET.
+   DB should have a write lock for the directory containing SOURCE.
 
-   *WORK_ITEM will be allocated in RESULT_POOL. All temporary allocations
-   will be allocated in SCRATCH_POOL.  */
+   Allocate *WORK_ITEM in RESULT_POOL. */
 static svn_error_t*
 save_merge_result(svn_skel_t **work_item,
                   svn_wc__db_t *db,
-                  const char *target_abspath,
-                  const char *result_target,
+                  const char *versioned_abspath,
+                  const char *source,
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
 {
   const char *edited_copy_abspath;
   const char *dir_abspath;
-  const char *merge_filename;
+  const char *filename;
 
-  svn_dirent_split(target_abspath, &dir_abspath, &merge_filename,
+  svn_dirent_split(&dir_abspath, &filename, versioned_abspath,
                    scratch_pool);
 
   /* ### Should use preserved-conflict-file-exts. */
@@ -430,42 +435,46 @@ save_merge_result(svn_skel_t **work_item
   SVN_ERR(svn_io_open_uniquely_named(NULL,
                                      &edited_copy_abspath,
                                      dir_abspath,
-                                     merge_filename,
+                                     filename,
                                      ".edited",
                                      svn_io_file_del_none,
                                      scratch_pool, scratch_pool));
   SVN_ERR(svn_wc__loggy_translated_file(work_item,
                                         db, dir_abspath,
                                         edited_copy_abspath,
-                                        result_target,
-                                        target_abspath,
+                                        source,
+                                        versioned_abspath,
                                         result_pool));
 
   return SVN_NO_ERROR;
 }
 
-/* Deal with the RESULT of the conflict resolution callback.
- * LEFT, RIGHT, and MERGE_TARGET are the files involved in
- * the 3-way merge.  Store the result of the 3-way merge in
- * MERGE_OUTCOME.  If the callback did not provide the name to
- * a merged file, use RESULT_TARGET is a fallback.
- * DETRANSLATED_TARGET is the detranslated version of MERGE_TARGET
- * (see detranslate_wc_file() above).  OPTIONS are passed to the
- * diff3 implementation in case a 3-way  merge has to be carried out.
- * Do all allocations in POOL. */
+/* Deal with the result of the conflict resolution callback, as indicated by
+ * CHOICE.
+ *
+ * Set *WORK_ITEMS to new work items that will ...
+ * Set *MERGE_OUTCOME to the result of the 3-way merge.
+ *
+ * LEFT_ABSPATH, RIGHT_ABSPATH, and TARGET_ABSPATH are the input files to
+ * the 3-way merge, and MERGED_FILE is the merged result as generated by the
+ * internal or external merge or by the conflict resolution callback.
+ *
+ * DETRANSLATED_TARGET is the detranslated version of TARGET_ABSPATH
+ * (see detranslate_wc_file() above).  DIFF3_OPTIONS are passed to the
+ * diff3 implementation in case a 3-way merge has to be carried out. */
 static svn_error_t*
 eval_conflict_func_result(svn_skel_t **work_items,
                           enum svn_wc_merge_outcome_t *merge_outcome,
-                          svn_wc_conflict_result_t *result,
+                          svn_wc_conflict_choice_t choice,
                           svn_wc__db_t *db,
+                          const char *wri_abspath,
                           const char *left_abspath,
                           const char *right_abspath,
                           const char *target_abspath,
                           const char *copyfrom_text,
-                          const char *adm_abspath,
-                          const char *result_target,
+                          const char *merged_file,
                           const char *detranslated_target,
-                          svn_diff_file_options_t *options,
+                          svn_diff_file_options_t *diff3_options,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
 {
@@ -475,7 +484,7 @@ eval_conflict_func_result(svn_skel_t **w
 
   *work_items = NULL;
 
-  switch (result->choice)
+  switch (choice)
     {
       /* If the callback wants to use one of the fulltexts
          to resolve the conflict, so be it.*/
@@ -506,11 +515,11 @@ eval_conflict_func_result(svn_skel_t **w
           svn_diff_t *diff;
           svn_diff_conflict_display_style_t style;
 
-          style = result->choice == svn_wc_conflict_choose_theirs_conflict
+          style = choice == svn_wc_conflict_choose_theirs_conflict
                     ? svn_diff_conflict_display_latest
                     : svn_diff_conflict_display_modified;
 
-          SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir, db, adm_abspath,
+          SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir, db, wri_abspath,
                                                  pool, pool));
           SVN_ERR(svn_stream_open_unique(&chosen_stream, &chosen_path,
                                          temp_dir,
@@ -519,7 +528,7 @@ eval_conflict_func_result(svn_skel_t **w
           SVN_ERR(svn_diff_file_diff3_2(&diff,
                                         left_abspath,
                                         detranslated_target, right_abspath,
-                                        options, pool));
+                                        diff3_options, pool));
           SVN_ERR(svn_diff_file_output_merge2(chosen_stream, diff,
                                               left_abspath,
                                               detranslated_target,
@@ -545,10 +554,7 @@ eval_conflict_func_result(svn_skel_t **w
            good to use". */
       case svn_wc_conflict_choose_merged:
         {
-          /* Look for callback's own merged-file first:  */
-          install_from = (result->merged_file
-                            ? result->merged_file
-                            : result_target);
+          install_from = merged_file;
           *merge_outcome = svn_wc_merge_merged;
           break;
         }
@@ -600,10 +606,27 @@ eval_conflict_func_result(svn_skel_t **w
   return SVN_NO_ERROR;
 }
 
-/* Preserve the three pre-merge files, and modify the
-   entry (mark as conflicted, track the preserved files). */
-static svn_error_t*
+/* Preserve the three pre-merge files.
+
+   Create three empty files, with unique names that each include the
+   basename of TARGET_ABSPATH and one of LEFT_LABEL, RIGHT_LABEL and
+   TARGET_LABEL, in the directory that contains TARGET_ABSPATH.  Typical
+   names are "foo.c.r37" or "foo.c.2.mine".  Set *LEFT_COPY, *RIGHT_COPY and
+   *TARGET_COPY to their absolute paths.
+
+   Set *WORK_ITEMS to a list of new work items that will write copies of
+   LEFT_ABSPATH, RIGHT_ABSPATH and TARGET_ABSPATH into the three files,
+   translated to working-copy form.
+
+   The translation to working-copy form will be done according to the
+   versioned properties of TARGET_ABSPATH that are current when the work
+   queue items are executed.
+*/
+static svn_error_t *
 preserve_pre_merge_files(svn_skel_t **work_items,
+                         const char **left_copy,
+                         const char **right_copy,
+                         const char **target_copy,
                          svn_wc__db_t *db,
                          const char *left_abspath,
                          const char *right_abspath,
@@ -616,52 +639,29 @@ preserve_pre_merge_files(svn_skel_t **wo
                          apr_pool_t *result_pool,
                          apr_pool_t *scratch_pool)
 {
-  apr_pool_t *pool = scratch_pool;  /* ### temporary rename  */
-  const char *left_copy, *right_copy, *target_copy;
   const char *tmp_left, *tmp_right, *detranslated_target_copy;
   const char *dir_abspath, *target_name;
   const char *temp_dir;
-  svn_wc_entry_t tmp_entry;
   svn_skel_t *work_item;
 
   *work_items = NULL;
 
-  svn_dirent_split(target_abspath, &dir_abspath, &target_name, pool);
+  svn_dirent_split(&dir_abspath, &target_name, target_abspath, scratch_pool);
   SVN_ERR(svn_wc__db_temp_wcroot_tempdir(&temp_dir, db, target_abspath,
-                                         pool, pool));
-
-  /* I miss Lisp. */
-
-  SVN_ERR(svn_io_open_uniquely_named(NULL,
-                                     &left_copy,
-                                     dir_abspath,
-                                     target_name,
-                                     left_label,
-                                     svn_io_file_del_none,
-                                     pool, pool));
-
-  /* Have I mentioned how much I miss Lisp? */
-
-  SVN_ERR(svn_io_open_uniquely_named(NULL,
-                                     &right_copy,
-                                     dir_abspath,
-                                     target_name,
-                                     right_label,
-                                     svn_io_file_del_none,
-                                     pool, pool));
+                                         scratch_pool, scratch_pool));
 
-  /* Why, how much more pleasant to be forced to unroll my loops.
-     If I'd been writing in Lisp, I might have mapped an inline
-     lambda form over a list, or something equally disgusting.
-     Thank goodness C was here to protect me! */
-
-  SVN_ERR(svn_io_open_uniquely_named(NULL,
-                                     &target_copy,
-                                     dir_abspath,
-                                     target_name,
-                                     target_label,
-                                     svn_io_file_del_none,
-                                     pool, pool));
+  /* Create three empty files in DIR_ABSPATH, naming them with unique names
+     that each include TARGET_NAME and one of {LEFT,RIGHT,TARGET}_LABEL,
+     and set *{LEFT,RIGHT,TARGET}_COPY to those names. */
+  SVN_ERR(svn_io_open_uniquely_named(
+            NULL, left_copy, dir_abspath, target_name, left_label,
+            svn_io_file_del_none, scratch_pool, scratch_pool));
+  SVN_ERR(svn_io_open_uniquely_named(
+            NULL, right_copy, dir_abspath, target_name, right_label,
+            svn_io_file_del_none, scratch_pool, scratch_pool));
+  SVN_ERR(svn_io_open_uniquely_named(
+            NULL, target_copy, dir_abspath, target_name, target_label,
+            svn_io_file_del_none, scratch_pool, scratch_pool));
 
   /* We preserve all the files with keywords expanded and line
      endings in local (working) form. */
@@ -674,8 +674,8 @@ preserve_pre_merge_files(svn_skel_t **wo
     {
       SVN_ERR(svn_io_open_unique_file3(NULL, &tmp_left, temp_dir,
                                        svn_io_file_del_on_pool_cleanup,
-                                       pool, pool));
-      SVN_ERR(svn_io_copy_file(left_abspath, tmp_left, TRUE, pool));
+                                       scratch_pool, scratch_pool));
+      SVN_ERR(svn_io_copy_file(left_abspath, tmp_left, TRUE, scratch_pool));
     }
   else
     tmp_left = left_abspath;
@@ -684,8 +684,8 @@ preserve_pre_merge_files(svn_skel_t **wo
     {
       SVN_ERR(svn_io_open_unique_file3(NULL, &tmp_right, temp_dir,
                                        svn_io_file_del_on_pool_cleanup,
-                                       pool, pool));
-      SVN_ERR(svn_io_copy_file(right_abspath, tmp_right, TRUE, pool));
+                                       scratch_pool, scratch_pool));
+      SVN_ERR(svn_io_copy_file(right_abspath, tmp_right, TRUE, scratch_pool));
     }
   else
     tmp_right = right_abspath;
@@ -706,12 +706,12 @@ preserve_pre_merge_files(svn_skel_t **wo
      We use TARGET_ABSPATH's current properties to do the translation. */
   /* Derive the basenames of the 3 backup files. */
   SVN_ERR(svn_wc__loggy_translated_file(&work_item, db, dir_abspath,
-                                        left_copy, tmp_left,
+                                        *left_copy, tmp_left,
                                         target_abspath, result_pool));
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
 
   SVN_ERR(svn_wc__loggy_translated_file(&work_item, db, dir_abspath,
-                                        right_copy, tmp_right,
+                                        *right_copy, tmp_right,
                                         target_abspath, result_pool));
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
 
@@ -721,26 +721,12 @@ preserve_pre_merge_files(svn_skel_t **wo
            &detranslated_target_copy, target_abspath, db, target_abspath,
            SVN_WC_TRANSLATE_TO_NF | SVN_WC_TRANSLATE_NO_OUTPUT_CLEANUP,
            cancel_func, cancel_baton,
-           pool, pool));
+           scratch_pool, scratch_pool));
   SVN_ERR(svn_wc__loggy_translated_file(&work_item, db, dir_abspath,
-                                        target_copy, detranslated_target_copy,
+                                        *target_copy, detranslated_target_copy,
                                         target_abspath, result_pool));
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
 
-  tmp_entry.conflict_old = svn_dirent_is_child(dir_abspath, left_copy, pool);
-  tmp_entry.conflict_new = svn_dirent_is_child(dir_abspath, right_copy, pool);
-  tmp_entry.conflict_wrk = svn_dirent_basename(target_copy, pool);
-
-  /* Mark TARGET_ABSPATH's entry as "Conflicted", and start tracking
-     the backup files in the entry as well. */
-  SVN_ERR(svn_wc__loggy_entry_modify(&work_item, db, dir_abspath,
-                                     target_abspath, &tmp_entry,
-                                     SVN_WC__ENTRY_MODIFY_CONFLICT_OLD
-                                       | SVN_WC__ENTRY_MODIFY_CONFLICT_NEW
-                                       | SVN_WC__ENTRY_MODIFY_CONFLICT_WRK,
-                                     result_pool));
-  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
-
   return SVN_NO_ERROR;
 }
 
@@ -775,6 +761,8 @@ setup_text_conflict_desc(const char *lef
 }
 
 /* XXX Insane amount of parameters... */
+/* RESULT_TARGET is the path to the merged file produced by the internal or
+   external 3-way merge. */
 static svn_error_t*
 maybe_resolve_conflicts(svn_skel_t **work_items,
                         svn_wc__db_t *db,
@@ -799,14 +787,13 @@ maybe_resolve_conflicts(svn_skel_t **wor
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
-  apr_pool_t *pool = scratch_pool;  /* ### temporary rename  */
-  svn_wc_conflict_result_t *result = NULL;
+  svn_wc_conflict_result_t *result;
   const char *dir_abspath;
   svn_skel_t *work_item;
 
   *work_items = NULL;
 
-  dir_abspath = svn_dirent_dirname(target_abspath, pool);
+  dir_abspath = svn_dirent_dirname(target_abspath, scratch_pool);
 
   /* Give the conflict resolution callback a chance to clean
      up the conflicts before we mark the file 'conflicted' */
@@ -815,7 +802,7 @@ maybe_resolve_conflicts(svn_skel_t **wor
       /* If there is no interactive conflict resolution then we are effectively
          postponing conflict resolution. */
       result = svn_wc_create_conflict_result(svn_wc_conflict_choose_postpone,
-                                             NULL, pool);
+                                             NULL, scratch_pool);
     }
   else
     {
@@ -830,9 +817,9 @@ maybe_resolve_conflicts(svn_skel_t **wor
                                        detranslated_target,
                                        mimeprop,
                                        FALSE,
-                                       pool);
+                                       scratch_pool);
 
-      SVN_ERR(conflict_func(&result, cdesc, conflict_baton, pool));
+      SVN_ERR(conflict_func(&result, cdesc, conflict_baton, scratch_pool));
       if (result == NULL)
         return svn_error_create(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
                                 NULL, _("Conflict callback violated API:"
@@ -854,14 +841,15 @@ maybe_resolve_conflicts(svn_skel_t **wor
 
   SVN_ERR(eval_conflict_func_result(&work_item,
                                     merge_outcome,
-                                    result,
-                                    db,
+                                    result->choice,
+                                    db, dir_abspath,
                                     left_abspath,
                                     right_abspath,
                                     target_abspath,
                                     copyfrom_text,
-                                    dir_abspath,
-                                    result_target,
+                                    result->merged_file
+                                      ? result->merged_file
+                                      : result_target,
                                     detranslated_target,
                                     options,
                                     result_pool, scratch_pool));
@@ -873,18 +861,6 @@ maybe_resolve_conflicts(svn_skel_t **wor
     return SVN_NO_ERROR;
 
   /* The conflicts have not been dealt with. */
-  SVN_ERR(preserve_pre_merge_files(&work_item,
-                                   db,
-                                   left_abspath,
-                                   right_abspath,
-                                   target_abspath,
-                                   left_label,
-                                   right_label,
-                                   target_label,
-                                   cancel_func, cancel_baton,
-                                   result_pool, scratch_pool));
-  *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
-
   *merge_outcome = svn_wc_merge_conflict;
 
   return SVN_NO_ERROR;
@@ -926,7 +902,7 @@ merge_text_file(svn_skel_t **work_items,
 
   *work_items = NULL;
 
-  svn_dirent_split(target_abspath, &dir_abspath, &base_name, pool);
+  svn_dirent_split(&dir_abspath, &base_name, target_abspath, pool);
 
   /* Open a second temporary file for writing; this is where diff3
      will write the merged results.  We want to use a tempfile
@@ -943,7 +919,7 @@ merge_text_file(svn_skel_t **work_items,
   if (merge_options)
     SVN_ERR(svn_diff_file_options_parse(options, merge_options, pool));
 
-  /* Run an external merge if requested. */
+  /* Run the external or internal merge, as requested. */
   if (diff3_cmd)
       SVN_ERR(do_text_merge_external(&contains_conflicts,
                                      result_f,
@@ -968,7 +944,6 @@ merge_text_file(svn_skel_t **work_items,
                           options,
                           pool));
 
-  /* Close the output file */
   SVN_ERR(svn_io_file_close(result_f, pool));
 
   if (contains_conflicts && ! dry_run)
@@ -993,6 +968,34 @@ merge_text_file(svn_skel_t **work_items,
                                       cancel_func, cancel_baton,
                                       result_pool, scratch_pool));
 
+      if (*merge_outcome == svn_wc_merge_conflict)
+        {
+          svn_skel_t *work_item;
+          const char *left_copy, *right_copy, *target_copy;
+
+          /* Preserve the three conflict files */
+          SVN_ERR(preserve_pre_merge_files(
+                    &work_item,
+                    &left_copy, &right_copy, &target_copy,
+                    db,
+                    left_abspath, right_abspath, target_abspath,
+                    left_label, right_label, target_label,
+                    cancel_func, cancel_baton,
+                    result_pool, scratch_pool));
+          *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+
+          /* Track the three conflict files in the metadata.
+           * ### TODO WC-NG: Do this outside the work queue: see
+           * svn_wc__wq_tmp_build_set_text_conflict_markers()'s doc string. */
+          SVN_ERR(svn_wc__wq_tmp_build_set_text_conflict_markers(
+                            &work_item, db, target_abspath,
+                            svn_dirent_basename(left_copy, NULL),
+                            svn_dirent_basename(right_copy, NULL),
+                            svn_dirent_basename(target_copy, NULL),
+                            result_pool, scratch_pool));
+          *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
+        }
+
       if (*merge_outcome == svn_wc_merge_merged)
         return SVN_NO_ERROR;
     }
@@ -1062,14 +1065,14 @@ merge_binary_file(svn_skel_t **work_item
   const char *left_copy, *right_copy;
   const char *left_base, *right_base;
   const char *merge_dirpath, *merge_filename;
-  svn_wc_entry_t tmp_entry;
+  const char *conflict_wrk;
   svn_skel_t *work_item;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
 
   *work_items = NULL;
 
-  svn_dirent_split(target_abspath, &merge_dirpath, &merge_filename, pool);
+  svn_dirent_split(&merge_dirpath, &merge_filename, target_abspath, pool);
 
   /* Give the conflict resolution callback a chance to clean
      up the conflict before we mark the file 'conflicted' */
@@ -1198,11 +1201,11 @@ merge_binary_file(svn_skel_t **work_item
 
       mine_copy = svn_dirent_is_child(merge_dirpath,
                                       mine_copy, pool);
-      tmp_entry.conflict_wrk = mine_copy;
+      conflict_wrk = mine_copy;
     }
   else
     {
-      tmp_entry.conflict_wrk = NULL;
+      conflict_wrk = NULL;
     }
 
   /* Derive the basenames of the backup files. */
@@ -1211,16 +1214,14 @@ merge_binary_file(svn_skel_t **work_item
 
   /* Mark target_abspath's entry as "Conflicted", and start tracking
      the backup files in the entry as well. */
-  tmp_entry.conflict_old = left_base;
-  tmp_entry.conflict_new = right_base;
-  SVN_ERR(svn_wc__loggy_entry_modify(
-            &work_item,
-            db, merge_dirpath, target_abspath,
-            &tmp_entry,
-            SVN_WC__ENTRY_MODIFY_CONFLICT_OLD
-              | SVN_WC__ENTRY_MODIFY_CONFLICT_NEW
-              | SVN_WC__ENTRY_MODIFY_CONFLICT_WRK,
-            result_pool));
+  SVN_ERR(svn_wc__wq_tmp_build_set_text_conflict_markers(&work_item,
+                                                         db, target_abspath,
+                                                         left_base,
+                                                         right_base,
+                                                         conflict_wrk,
+                                                         result_pool,
+                                                         scratch_pool));
+
   *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
 
   *merge_outcome = svn_wc_merge_conflict; /* a conflict happened */