Author: rhuijben
Date: Mon Mar 15 00:29:53 2010
New Revision: 923019
URL: http://svn.apache.org/viewvc?rev=923019&view=rev
Log:
Remove four more svn_wc__entry_modify2() calls by creating a wc_db
operation for making a copy from the current node state to WORKING_NODE.
This function provides the implementation for
schedule_existing_item_for_re_add() (update_editor.c) and
mark_tree_copied() (adm_ops.c, svn_wc_add4()).
This patch removes schedule_existing_item_for_re_add(), but doesn't touch
mark_tree_copied() yet as time is up for today.
* subversion/libsvn_wc/update_editor.c
(set_copied_baton_t): Remove baton.
(set_copied_callback): Remove function.
(schedule_existing_item_for_re_add): Remove function.
(do_entry_deletion): Update caller.
* subversion/libsvn_wc/wc-queries.sql
(STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE,
STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE,
STMT_UPDATE_COPYFROM): New queries.
* subversion/libsvn_wc/wc_db.c
(make_copy_baton): New struct.
(make_copy_txn): New helper function.
(svn_wc__db_temp_op_make_copy): New function.
* subversion/libsvn_wc/wc_db.h
(svn_wc__db_temp_op_make_copy): New function.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/libsvn_wc/wc-queries.sql
subversion/trunk/subversion/libsvn_wc/wc_db.c
subversion/trunk/subversion/libsvn_wc/wc_db.h
Modified: subversion/trunk/subversion/libsvn_wc/update_editor.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/update_editor.c?rev=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Mon Mar 15 00:29:53
2010
@@ -2055,217 +2055,6 @@ node_already_conflicted(svn_boolean_t *c
return SVN_NO_ERROR;
}
-
-/* A walk baton for schedule_existing_item_for_re_add()'s call
- to svn_wc__internal_walk_children(). */
-struct set_copied_baton_t
-{
- svn_wc__db_t *db;
-
- /* The PATH arg to schedule_existing_item_for_re_add(). */
- const char *added_subtree_root_path;
-};
-
-/* An svn_wc__node_found_func_t callback function.
- * Set the 'copied' flag on the given ENTRY for every PATH
- * under ((set_copied_baton_t *)WALK_BATON)->ADDED_SUBTREE_ROOT_PATH
- * which has a normal schedule. */
-static svn_error_t *
-set_copied_callback(const char *local_abspath,
- void *walk_baton,
- apr_pool_t *scratch_pool)
-{
- struct set_copied_baton_t *b = walk_baton;
- svn_wc__db_status_t status;
- svn_wc__db_kind_t kind;
-
- if (strcmp(local_abspath, b->added_subtree_root_path) == 0)
- return SVN_NO_ERROR; /* Don't touch the root */
-
- 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,
- b->db, local_abspath,
- scratch_pool, scratch_pool));
-
- if (kind == svn_wc__db_kind_dir)
- {
- /* We don't want to mark a deleted PATH as copied. If PATH
- is added without history we don't want to make it look like
- it has history. If PATH is replaced we don't want to make
- it look like it has history if it doesn't. Only if PATH is
- schedule normal do we need to mark it as copied. */
- if (status == svn_wc__db_status_normal)
- {
- svn_wc_entry_t tmp_entry;
-
- /* Set the 'copied' flag and write the entry out to disk. */
- tmp_entry.copied = TRUE;
- SVN_ERR(svn_wc__entry_modify2(b->db,
- local_abspath,
- svn_node_dir,
- TRUE,
- &tmp_entry,
- SVN_WC__ENTRY_MODIFY_COPIED,
- scratch_pool));
- }
- }
-
- /* We don't want to mark a deleted PATH as copied. If PATH
- is added without history we don't want to make it look like
- it has history. If PATH is replaced we don't want to make
- it look like it has history if it doesn't. Only if PATH is
- schedule normal do we need to mark it as copied. */
- if (status == svn_wc__db_status_normal)
- {
- svn_wc_entry_t tmp_entry;
- apr_hash_t *props;
-
- /* We switch the node from BASE to WORKING.. We have to move the
- properties with it */
- SVN_ERR(svn_wc__db_read_pristine_props(&props, b->db, local_abspath,
- scratch_pool, scratch_pool));
-
- /* Set the 'copied' flag and write the entry out to disk. */
- tmp_entry.copied = TRUE;
- SVN_ERR(svn_wc__entry_modify2(b->db,
- local_abspath,
- kind == svn_wc__db_kind_dir
- ? svn_node_dir
- : svn_node_file,
- FALSE,
- &tmp_entry,
- SVN_WC__ENTRY_MODIFY_COPIED,
- scratch_pool));
-
- SVN_ERR(svn_wc__db_temp_op_set_pristine_props(b->db, local_abspath,
props,
- TRUE, scratch_pool));
- }
- return SVN_NO_ERROR;
-}
-
-/* Schedule the WC item LOCAL_ABSPATH for re-addition by copying its BASE_NODE
- * information to WORKING_NODE where necessary.
- *.
- * If MODIFY_COPYFROM is TRUE, re-add the item as a copy with history
- * of node-...@node-rev.
- * Assume that the item exists locally and is scheduled as still existing with
- * some local modifications relative to its (old) base, but does not exist in
- * the repository at the target revision.
- *
- * Use the local content of the item, even if it
- * If the item is a directory, recursively schedule its contents to be the
- * contents of the re-added tree, even if they are locally modified relative
- * to it.
- *
- * THEIR_REPOS_RELPATH is the deleted node's repos-relpath on the source-
- * right side, the side that the target should become after the update. In
- * other words, that's the new repos-relpath the node would have if it were
- * not deleted.
- *
- * Make changes immediately, not loggily, because that is easier to keep
- * track of when multiple directories are involved. */
-static svn_error_t *
-schedule_existing_item_for_re_add(svn_wc__db_t *db,
- const char *local_abspath,
- const char *their_repos_relpath,
- svn_boolean_t modify_copyfrom,
- apr_pool_t *pool)
-{
- svn_wc_entry_t tmp_entry;
- apr_uint64_t flags = 0;
- apr_hash_t *props;
- const svn_wc_entry_t *entry;
- const char *repos_root;
- svn_error_t *err;
-
- SVN_ERR(svn_wc__db_scan_base_repos(NULL, &repos_root, NULL, db,
local_abspath,
- pool, pool));
-
- err = svn_wc__get_entry(&entry, db, local_abspath,
- FALSE /* allow_unversioned */, svn_node_unknown,
- TRUE /* need_parent_stub */, pool, pool);
- if (err)
- {
- if (err->apr_err != SVN_ERR_NODE_UNEXPECTED_KIND)
- return svn_error_return(err);
-
- /* The node was a file, and we got the "real" entry, not the stub.
- That is just what we'd like. */
- svn_error_clear(err);
- }
-
- SVN_ERR(svn_wc__db_read_pristine_props(&props, db, local_abspath,
- pool, pool));
-
- /* Update the details of the base rev/url to reflect the incoming
- * delete, while leaving the working version as it is, scheduling it
- * for re-addition unless it was already non-existent. */
- tmp_entry.url = svn_path_url_add_component2(repos_root,
- their_repos_relpath, pool);
- flags |= SVN_WC__ENTRY_MODIFY_URL;
-
- /* Schedule the working version to be re-added. */
- tmp_entry.schedule = svn_wc_schedule_add;
- flags |= SVN_WC__ENTRY_MODIFY_SCHEDULE;
- flags |= SVN_WC__ENTRY_MODIFY_FORCE;
-
- if (modify_copyfrom)
- {
- tmp_entry.copyfrom_url = entry->url;
- flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_URL;
- tmp_entry.copyfrom_rev = entry->revision;
- flags |= SVN_WC__ENTRY_MODIFY_COPYFROM_REV;
- tmp_entry.copied = TRUE;
- flags |= SVN_WC__ENTRY_MODIFY_COPIED;
- }
-
- /* ### Need to change the "base" into a "revert-base" ? */
-
- /* Determine which adm dir holds this node's entry */
- SVN_ERR(svn_wc__entry_modify2(db,
- local_abspath,
- entry->kind,
- FALSE,
- &tmp_entry,
- flags, pool));
-
- SVN_ERR(svn_wc__db_temp_op_set_pristine_props(db, local_abspath, props,
- TRUE, pool));
-
- /* If it's a directory, set the 'copied' flag recursively. The rest of the
- * directory tree's state can stay exactly as it was before being
- * scheduled for re-add. */
- /* ### BH: I don't think this code handles switched subpaths, excluded
- and absent items in any usefull way. Needs carefull redesign */
- if (entry->kind == svn_node_dir)
- {
- struct set_copied_baton_t set_copied_baton;
-
- /* Set the 'copied' flag recursively, to support the
- * cases where this is a directory. */
- set_copied_baton.db = db;
- set_copied_baton.added_subtree_root_path = local_abspath;
- SVN_ERR(svn_wc__internal_walk_children(db, local_abspath, FALSE,
- set_copied_callback,
- &set_copied_baton,
- svn_depth_infinity,
- NULL, NULL, pool));
-
- /* If PATH is a directory then we must also record in PARENT_PATH's
- entry that we are re-adding PATH. */
- flags &= ~SVN_WC__ENTRY_MODIFY_URL;
- SVN_ERR(svn_wc__entry_modify2(db, local_abspath, svn_node_dir, TRUE,
- &tmp_entry, flags, pool));
-
- /* ### Need to do something more, such as change 'base' into
- ### 'revert-base'? */
- }
-
- return SVN_NO_ERROR;
-}
-
/* Delete PATH from its immediate parent PARENT_PATH, in the edit
* represented by EB. PATH is relative to EB->anchor.
* PARENT_PATH is relative to the current working directory.
@@ -2368,9 +2157,9 @@ do_entry_deletion(struct edit_baton *eb,
SVN_ERR(svn_wc__wq_add_loggy(eb->db, dir_abspath, log_item, pool));
SVN_ERR(svn_wc__run_log2(eb->db, dir_abspath, pool));
- SVN_ERR(schedule_existing_item_for_re_add(eb->db, local_abspath,
- their_relpath, TRUE,
- pool));
+ SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath, TRUE,
+ pool));
+
return SVN_NO_ERROR;
}
else if (tree_conflict->reason == svn_wc_conflict_reason_deleted)
@@ -2397,9 +2186,9 @@ do_entry_deletion(struct edit_baton *eb,
SVN_ERR(svn_wc__wq_add_loggy(eb->db, dir_abspath, log_item, pool));
SVN_ERR(svn_wc__run_log2(eb->db, dir_abspath, pool));
- SVN_ERR(schedule_existing_item_for_re_add(eb->db, local_abspath,
- their_relpath, FALSE,
- pool));
+ SVN_ERR(svn_wc__db_temp_op_make_copy(eb->db, local_abspath, TRUE,
+ pool));
+
return SVN_NO_ERROR;
}
else
Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Mon Mar 15 00:29:53
2010
@@ -329,6 +329,32 @@ SELECT wc_id, local_relpath, parent_relp
symlink_target, last_mod_time FROM BASE_NODE
WHERE wc_id = ?1 AND local_relpath = ?2;
+-- STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE
+INSERT INTO WORKING_NODE (
+ wc_id, local_relpath, parent_relpath, presence, kind, checksum,
+ translated_size, changed_rev, changed_date, changed_author, depth,
+ symlink_target, last_mod_time, properties, copyfrom_repos_id,
+ copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, local_relpath, parent_relpath, 'normal', kind, checksum,
+ translated_size, changed_rev, changed_date, changed_author, depth,
+ symlink_target, last_mod_time, properties, repos_id,
+ repos_relpath, revnum FROM BASE_NODE
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE
+INSERT INTO WORKING_NODE (
+ wc_id, local_relpath, parent_relpath, presence, kind, changed_rev,
+ changed_date, changed_author, copyfrom_repos_id,
+ copyfrom_repos_path, copyfrom_revnum )
+SELECT wc_id, local_relpath, parent_relpath, 'not-present', kind, changed_rev,
+ changed_date, changed_author, repos_id,
+ repos_relpath, revnum FROM BASE_NODE
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
+-- STMT_UPDATE_COPYFROM (
+UPDATE WORKING_NODE set copyfrom_repos_id = ?3, copyfrom_repos_path = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2;
+
/* ------------------------------------------------------------------------- */
/* these are used in entries.c */
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Mon Mar 15 00:29:53 2010
@@ -6438,3 +6438,330 @@ svn_wc__db_temp_op_start_directory_updat
return SVN_NO_ERROR;
}
+
+/* Baton for make_copy_txn */
+struct make_copy_baton
+{
+ svn_wc__db_t *db;
+ const char *local_abspath;
+
+ svn_wc__db_pdh_t *pdh;
+ const char *local_relpath;
+ svn_boolean_t remove_base;
+ svn_boolean_t is_root;
+};
+
+/* Transaction callback for svn_wc__db_temp_op_make_copy */
+static svn_error_t *
+make_copy_txn(void *baton,
+ svn_sqlite__db_t *sdb,
+ apr_pool_t *scratch_pool)
+{
+ struct make_copy_baton *mcb = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ svn_boolean_t remove_working = FALSE;
+ svn_boolean_t check_base = TRUE;
+ svn_boolean_t add_working_normal = FALSE;
+ svn_boolean_t add_working_not_present = FALSE;
+ const apr_array_header_t *children;
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ int i;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (have_row)
+ {
+ svn_wc__db_status_t working_status;
+
+ working_status = svn_sqlite__column_token(stmt, 0, presence_map);
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ SVN_ERR_ASSERT(working_status == svn_wc__db_status_normal
+ || working_status == svn_wc__db_status_base_deleted
+ || working_status == svn_wc__db_status_not_present
+ || working_status == svn_wc__db_status_incomplete);
+
+ /* Make existing deletions of BASE_NODEs remove WORKING_NODEs */
+ if (working_status == svn_wc__db_status_base_deleted)
+ {
+ remove_working = TRUE;
+ add_working_not_present = TRUE;
+ }
+
+ check_base = FALSE;
+ }
+ else
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (check_base)
+ {
+ svn_wc__db_status_t base_status;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_BASE_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is", mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ /* If there is no BASE_NODE, we don't have to copy anything */
+ if (!have_row)
+ return svn_error_return(svn_sqlite__reset(stmt));
+
+ base_status = svn_sqlite__column_token(stmt, 2, presence_map);
+
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ switch (base_status)
+ {
+ case svn_wc__db_status_normal:
+ case svn_wc__db_status_incomplete:
+ add_working_normal = TRUE;
+ break;
+ case svn_wc__db_status_not_present:
+ add_working_not_present = TRUE;
+ break;
+ case svn_wc__db_status_excluded:
+ case svn_wc__db_status_absent:
+ /* ### Make the copy match the WC or the repository? */
+ add_working_not_present = TRUE; /* ### Match WC */
+ break;
+ default:
+ SVN_ERR_MALFUNCTION();
+ }
+ }
+
+ /* Get the BASE children, as WORKING children don't need modifications */
+ SVN_ERR(svn_wc__db_base_get_children(&children, mcb->db, mcb->local_abspath,
+ scratch_pool, iterpool));
+
+ for (i = 0; i < children->nelts; i++)
+ {
+ const char *name = APR_ARRAY_IDX(children, i, const char *);
+ struct make_copy_baton cbt;
+
+ svn_pool_clear(iterpool);
+ cbt.local_abspath = svn_dirent_join(mcb->local_abspath, name, iterpool);
+
+ SVN_ERR(parse_local_abspath(&cbt.pdh, &cbt.local_relpath, mcb->db,
+ cbt.local_abspath,
+ svn_sqlite__mode_readwrite,
+ iterpool, iterpool));
+
+ VERIFY_USABLE_PDH(cbt.pdh);
+
+ cbt.db = mcb->db;
+ cbt.remove_base = mcb->remove_base;
+ cbt.is_root = FALSE;
+
+ SVN_ERR(make_copy_txn(&cbt, cbt.pdh->wcroot->sdb, iterpool));
+ }
+
+ if (remove_working)
+ {
+ /* Remove current WORKING_NODE record */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_DELETE_WORKING_NODE));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ if (add_working_normal)
+ {
+ /* Add a copy of the BASE_NODE to WORKING_NODE */
+
+ SVN_ERR(svn_sqlite__get_statement(
+ &stmt, sdb,
+ STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+ else if (add_working_not_present)
+ {
+ /* Add a not present WORKING_NODE */
+
+ SVN_ERR(svn_sqlite__get_statement(
+ &stmt, sdb,
+ STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ if (mcb->is_root && (add_working_normal || add_working_not_present))
+ {
+ const char *repos_relpath, *repos_root_url, *repos_uuid;
+ apr_int64_t repos_id;
+ /* Make sure the copy origin is set on the root even if the node
+ didn't have a local relpath */
+
+ SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+ &repos_uuid, mcb->db,
+ mcb->local_abspath,
+ iterpool, iterpool));
+
+ SVN_ERR(create_repos_id(&repos_id, repos_root_url, repos_uuid, sdb,
+ iterpool));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPDATE_COPYFROM));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isis",
+ mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath,
+ repos_id,
+ repos_relpath));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ /* And now, do the same for the parent stub :( */
+ if (remove_working)
+ {
+ const char *local_relpath;
+ svn_wc__db_pdh_t *pdh;
+
+ /* Remove WORKING_NODE stub */
+ SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+ svn_sqlite__mode_readwrite,
+ iterpool));
+ local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+ VERIFY_USABLE_PDH(pdh);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_DELETE_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ if (add_working_normal)
+ {
+ const char *local_relpath;
+ svn_wc__db_pdh_t *pdh;
+
+ /* Add a copy of the BASE_NODE to WORKING_NODE for the stub */
+ SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+ svn_sqlite__mode_readwrite,
+ iterpool));
+ local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+ VERIFY_USABLE_PDH(pdh);
+
+ /* Remove old data */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_DELETE_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ /* And insert the right data */
+ SVN_ERR(svn_sqlite__get_statement(
+ &stmt, pdh->wcroot->sdb,
+ STMT_INSERT_WORKING_NODE_NORMAL_FROM_BASE_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+ else if (add_working_not_present)
+ {
+ const char *local_relpath;
+ svn_wc__db_pdh_t *pdh;
+
+ /* Add a not present WORKING_NODE stub */
+ SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+ svn_sqlite__mode_readwrite,
+ iterpool));
+ local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+ VERIFY_USABLE_PDH(pdh);
+
+ /* Remove old data */
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_DELETE_WORKING_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ /* And insert the right data */
+ SVN_ERR(svn_sqlite__get_statement(
+ &stmt, pdh->wcroot->sdb,
+ STMT_INSERT_WORKING_NODE_NOT_PRESENT_FROM_BASE_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ /* Remove the BASE_NODE if the caller asked us to do that */
+ if (mcb->remove_base)
+ {
+ const char *local_relpath;
+ svn_wc__db_pdh_t *pdh;
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+ STMT_DELETE_BASE_NODE));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ mcb->pdh->wcroot->wc_id,
+ mcb->local_relpath));
+
+ SVN_ERR(svn_sqlite__step_done(stmt));
+
+ /* Remove BASE_NODE_STUB */
+ SVN_ERR(navigate_to_parent(&pdh, mcb->db, mcb->pdh,
+ svn_sqlite__mode_readwrite,
+ iterpool));
+ local_relpath = svn_dirent_basename(mcb->local_abspath, NULL);
+ VERIFY_USABLE_PDH(pdh);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, pdh->wcroot->sdb,
+ STMT_DELETE_BASE_NODE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step_done(stmt));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ flush_entries(mcb->pdh);
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__db_temp_op_make_copy(svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_boolean_t remove_base,
+ apr_pool_t *scratch_pool)
+{
+ struct make_copy_baton mcb;
+
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+ SVN_ERR(parse_local_abspath(&mcb.pdh, &mcb.local_relpath, db, local_abspath,
+ svn_sqlite__mode_readwrite,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_PDH(mcb.pdh);
+
+ mcb.db = db;
+ mcb.local_abspath = local_abspath;
+ mcb.is_root = TRUE;
+
+ SVN_ERR(svn_sqlite__with_transaction(mcb.pdh->wcroot->sdb,
+ make_copy_txn, &mcb,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=923019&r1=923018&r2=923019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Mon Mar 15 00:29:53 2010
@@ -2057,6 +2057,18 @@ svn_wc__db_temp_op_start_directory_updat
svn_revnum_t new_rev,
apr_pool_t *scratch_pool);
+/* Update WORKING_NODE to make it represent a copy of the current working
+ copy. Leaving additions and copies as-is, but making a copy of all the
+ required BASE_NODE data to WORKING_NODE, to allow removing and/or
+ updating the BASE_NODE without changing the contents of the current
+ working copy */
+svn_error_t *
+svn_wc__db_temp_op_make_copy(svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_boolean_t remove_base,
+ apr_pool_t *scratch_pool);
+
+
/** @} */