You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2010/08/09 16:52:56 UTC
svn commit: r983665 - in /subversion/trunk/subversion/libsvn_wc:
update_editor.c workqueue.c workqueue.h
Author: rhuijben
Date: Mon Aug 9 14:52:56 2010
New Revision: 983665
URL: http://svn.apache.org/viewvc?rev=983665&view=rev
Log:
Remove the usage of the last loggy operation by declaring a new workingqueue
operation.
The new workingqueue operation has a stricter description than the old
operation, but for this patch I start by just moving the original code
without applying the restrictions.
A separate commit will remove the loggy support from the workqueue.
* subversion/libsvn_wc/update_editor.c
(includes): Remove log.h
(do_entry_deletion): Queue base remove workqueue item and remove direct
removal on switch as svn_wc__internal_remove_from_revision_control
already checks this in a better way than described here.
* subversion/libsvn_wc/workqueue.c
(OP_BASE_REMOVE): New define.
(basic_delete_entry): New function. Copied from log.c
(run_base_remove): New function.
(svn_wc__wq_build_base_remove): New function.
(dispatch_table): Add OP_BASE_REMOVE.
* subversion/libsvn_wc/workqueue.h
(svn_wc__wq_build_base_remove): New function.
Modified:
subversion/trunk/subversion/libsvn_wc/update_editor.c
subversion/trunk/subversion/libsvn_wc/workqueue.c
subversion/trunk/subversion/libsvn_wc/workqueue.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=983665&r1=983664&r2=983665&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/update_editor.c Mon Aug 9 14:52:56 2010
@@ -48,7 +48,6 @@
#include "svn_iter.h"
#include "wc.h"
-#include "log.h"
#include "adm_files.h"
#include "entries.h"
#include "lock.h"
@@ -2219,56 +2218,21 @@ do_entry_deletion(struct edit_baton *eb,
if (strcmp(local_abspath, eb->target_abspath) != 0)
{
/* Delete, and do not leave a not-present node. */
- SVN_ERR(svn_wc__loggy_delete_entry(&work_item,
- eb->db, dir_abspath, local_abspath,
- SVN_INVALID_REVNUM,
- svn_wc__db_kind_unknown,
- pool));
+ SVN_ERR(svn_wc__wq_build_base_remove(&work_item,
+ eb->db, local_abspath, FALSE,
+ pool, pool));
SVN_ERR(svn_wc__db_wq_add(eb->db, dir_abspath, work_item, pool));
}
else
{
/* Delete, leaving a not-present node. */
- SVN_ERR(svn_wc__loggy_delete_entry(&work_item,
- eb->db, dir_abspath, local_abspath,
- *eb->target_revision,
- kind,
- pool));
+ SVN_ERR(svn_wc__wq_build_base_remove(&work_item,
+ eb->db, local_abspath, TRUE,
+ pool, pool));
SVN_ERR(svn_wc__db_wq_add(eb->db, dir_abspath, work_item, pool));
eb->target_deleted = TRUE;
}
- if (eb->switch_relpath)
- {
- /* The SVN_WC__LOG_DELETE_ENTRY log item will cause
- * svn_wc_remove_from_revision_control() to be run. But that
- * function checks whether the deletion target's URL is child of
- * its parent directory's URL, and if it's not, then the entry
- * in parent won't be deleted (because presumably the child
- * represents a disjoint working copy, i.e., it is a wc_root).
- *
- * However, during a switch this works against us, because by
- * the time we get here, the parent's URL has already been
- * changed. So we manually remove the child from revision
- * control after the delete-entry item has been written in the
- * parent's log, but before it is run, so the only work left for
- * the log item is to remove the entry in the parent directory.
- */
-
- if (kind == svn_wc__db_kind_dir)
- {
- SVN_ERR(leftmod_error_chain(
- svn_wc__internal_remove_from_revision_control(
- eb->db,
- local_abspath,
- TRUE, /* destroy */
- FALSE, /* instant error */
- eb->cancel_func,
- eb->cancel_baton,
- pool)));
- }
- }
-
/* Note: these two lines are duplicated in the tree-conflicts bail out
* above. */
SVN_ERR(svn_wc__wq_run(eb->db, dir_abspath,
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.c?rev=983665&r1=983664&r2=983665&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.c Mon Aug 9 14:52:56 2010
@@ -45,6 +45,7 @@
#define OP_REVERT "revert"
#define OP_KILLME "killme"
#define OP_LOGGY "loggy"
+#define OP_BASE_REMOVE "base-remove"
#define OP_DELETION_POSTCOMMIT "deletion-postcommit"
/* Arguments of OP_POSTCOMMIT:
* (local_abspath, revnum, date, [author], [checksum],
@@ -640,6 +641,177 @@ svn_wc__wq_add_killme(svn_wc__db_t *db,
#endif
/* ------------------------------------------------------------------------ */
+/* OP_REMOVE_BASE */
+
+/* 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.
+ * LOCAL_ABSPATH is the name of the file or directory to be deleted.
+ * If it is unversioned,
+ * do nothing and return no error. Otherwise, delete its WC entry and, if
+ * the working version is unmodified, delete it from disk. */
+static svn_error_t *
+basic_delete_entry(svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_kind_t kind;
+ svn_boolean_t hidden;
+ svn_error_t *err;
+
+ /* Figure out if 'name' is a dir or a file */
+ SVN_ERR(svn_wc__db_read_kind(&kind, db, local_abspath, TRUE, scratch_pool));
+ if (kind == svn_wc__db_kind_unknown)
+ return SVN_NO_ERROR; /* Already gone */
+
+ SVN_ERR(svn_wc__db_node_hidden(&hidden, db, local_abspath, scratch_pool));
+ if (hidden)
+ return SVN_NO_ERROR;
+
+ /* Remove the object from revision control -- whether it's a
+ single file or recursive directory removal. Attempt
+ to destroy all working files & dirs too.
+
+ ### We pass NULL, NULL for cancel_func and cancel_baton below.
+ ### If they were available, it would be nice to use them. */
+ if (kind == svn_wc__db_kind_dir)
+ {
+ svn_wc__db_status_t status;
+
+ SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+ if (status == svn_wc__db_status_obstructed ||
+ status == svn_wc__db_status_obstructed_add ||
+ status == svn_wc__db_status_obstructed_delete)
+ {
+ /* Removing a missing wcroot is easy, just remove its parent entry
+ ### BH: I can't tell why we don't use this for adds.
+ We might want to remove WC obstructions?
+
+ We don't have a missing status in the final version of WC-NG,
+ so why bother researching its history.
+ */
+ if (status != svn_wc__db_status_obstructed_add)
+ {
+ SVN_ERR(svn_wc__db_temp_op_remove_entry(db, local_abspath,
+ scratch_pool));
+
+ return SVN_NO_ERROR;
+ }
+ }
+ }
+
+ err = svn_wc__internal_remove_from_revision_control(db,
+ local_abspath,
+ TRUE, /* destroy */
+ FALSE, /* instant_error*/
+ NULL, NULL,
+ scratch_pool);
+
+ if (err && err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD)
+ {
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+ }
+ else
+ {
+ return svn_error_return(err);
+ }
+}
+
+/* Process the OP_REMOVE_BASE work item WORK_ITEM.
+ * See svn_wc__wq_build_remove_base() which generates this work item.
+ * Implements (struct work_item_dispatch).func. */
+
+static svn_error_t *
+run_base_remove(svn_wc__db_t *db,
+ const svn_skel_t *work_item,
+ const char *wri_abspath,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ const svn_skel_t *arg1 = work_item->children->next;
+ const char *local_abspath;
+ svn_boolean_t keep_not_present;
+ svn_revnum_t revision;
+ const char *repos_relpath, *repos_root_url, *repos_uuid;
+ svn_wc__db_kind_t kind;
+
+ local_abspath = apr_pstrmemdup(scratch_pool, arg1->data, arg1->len);
+ keep_not_present = svn_skel__parse_int(arg1->next, scratch_pool) != 0;
+
+ if (keep_not_present)
+ {
+ SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &revision, &repos_relpath,
+ &repos_root_url, &repos_uuid, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+
+ if (!repos_relpath)
+ SVN_ERR(svn_wc__db_scan_base_repos(&repos_relpath, &repos_root_url,
+ &repos_uuid,
+ db, local_abspath, scratch_pool,
+ scratch_pool));
+
+#ifndef SVN_WC__SINGLE_DB
+ /* ### When LOCAL_ABSPATH is obstructed, we might not receive a valid
+ ### revision here. For the small time that is left until Single-DB
+ ### just mark the not-present node as revision 0, as we are not
+ ### interested in the revision of not-present nodes anyway.
+
+ ### Triggered by update_tests.py 15: issue #919, updates that delete
+ */
+ if (!SVN_IS_VALID_REVNUM(revision))
+ revision = 0;
+#endif
+ }
+
+ SVN_ERR(basic_delete_entry(db, local_abspath, scratch_pool));
+
+ if (keep_not_present)
+ {
+ SVN_ERR(svn_wc__db_base_add_absent_node(db, local_abspath,
+ repos_relpath,
+ repos_root_url,
+ repos_uuid,
+ revision,
+ kind,
+ svn_wc__db_status_not_present,
+ NULL,
+ NULL,
+ scratch_pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_boolean_t keep_not_present,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ *work_item = svn_skel__make_empty_list(result_pool);
+
+ /* If a SOURCE_ABSPATH was provided, then put it into the skel. If this
+ value is not provided, then the file's pristine contents will be used. */
+
+ svn_skel__prepend_int(keep_not_present, *work_item, result_pool);
+ svn_skel__prepend_str(apr_pstrdup(result_pool, local_abspath),
+ *work_item, result_pool);
+ svn_skel__prepend_str(OP_BASE_REMOVE, *work_item, result_pool);
+
+ return SVN_NO_ERROR;
+}
/* OP_LOGGY */
@@ -2313,6 +2485,7 @@ static const struct work_item_dispatch d
{ OP_SYNC_FILE_FLAGS, run_sync_file_flags },
{ OP_PREJ_INSTALL, run_prej_install },
{ OP_RECORD_FILEINFO, run_record_fileinfo },
+ { OP_BASE_REMOVE, run_base_remove },
{ OP_TMP_SET_TEXT_CONFLICT_MARKERS, run_set_text_conflict_markers },
{ OP_TMP_SET_PROPERTY_CONFLICT_MARKER, run_set_property_conflict_marker },
{ OP_PRISTINE_GET_TRANSLATED, run_pristine_get_translated },
Modified: subversion/trunk/subversion/libsvn_wc/workqueue.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/workqueue.h?rev=983665&r1=983664&r2=983665&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/workqueue.h (original)
+++ subversion/trunk/subversion/libsvn_wc/workqueue.h Mon Aug 9 14:52:56 2010
@@ -196,6 +196,23 @@ svn_wc__wq_add_revert(svn_boolean_t *wil
svn_boolean_t use_commit_times,
apr_pool_t *scratch_pool);
+/* Set *WORK_ITEM to a new work item that will remove all the data of
+ the BASE_NODE of LOCAL_ABSPATH and all it's descendants, but keeping
+ any WORKING_NODE data.
+
+ ### This is only used from update_editor.c's do_entry_deletion() and
+ ### the current implementation doesn't check if it removes more than
+ ### just this documented behavior. (It is just a copy of the old loggy
+ ### code)
+ */
+svn_error_t *
+svn_wc__wq_build_base_remove(svn_skel_t **work_item,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_boolean_t keep_not_present,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
#ifndef SVN_WC__SINGLE_DB
/* Handle the old "KILLME" concept -- perform the actual deletion of a
subdir (or just its admin area) during post-commit processing of a