Author: sbutler
Date: Mon Jun 6 23:27:06 2011
New Revision: 1132834
URL: http://svn.apache.org/viewvc?rev=1132834&view=rev
Log:
Fix the move command for issue 3899 (auto resolve for wc-wc copies/moves).
* subversion/tests/cmdline/copy_tests.py
(copying_conflicts): Rename to...
(copy_and_move_conflicts): ...this and add test cases for moves.
* subversion/libsvn_client/copy.c
(do_wc_to_wc_moves_with_locks2): Let svn_wc_copy3() copy the items and
let svn_wc_delete4() delete them. This reverts r1061328.
* subversion/libsvn_wc/adm_ops.c
(attempt_deletion): New function.
(svn_wc_delete4): If a file has unresolved text or property conflicts,
delete conflict marker files.
Modified:
subversion/trunk/subversion/libsvn_client/copy.c
subversion/trunk/subversion/libsvn_wc/adm_ops.c
subversion/trunk/subversion/tests/cmdline/copy_tests.py
Modified: subversion/trunk/subversion/libsvn_client/copy.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/copy.c?rev=1132834&r1=1132833&r2=1132834&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/copy.c (original)
+++ subversion/trunk/subversion/libsvn_client/copy.c Mon Jun 6 23:27:06 2011
@@ -335,20 +335,14 @@ do_wc_to_wc_moves_with_locks2(void *bato
scratch_pool);
SVN_ERR(svn_wc_copy3(b->ctx->wc_ctx, b->pair->src_abspath_or_url,
- dst_abspath, TRUE /* metadata_only */,
+ dst_abspath, FALSE /* metadata_only */,
b->ctx->cancel_func, b->ctx->cancel_baton,
b->ctx->notify_func2, b->ctx->notify_baton2,
scratch_pool));
- /* Should we be using a workqueue for this move? It's not clear.
- What should happen if the copy above is interrupted? The user
- may want to abort the move and a workqueue might interfere with
- that. */
- SVN_ERR(svn_io_file_rename(b->pair->src_abspath_or_url, dst_abspath,
- scratch_pool));
-
SVN_ERR(svn_wc_delete4(b->ctx->wc_ctx, b->pair->src_abspath_or_url,
- TRUE, FALSE,
+ FALSE /* keep_local */,
+ FALSE /* delete_unversioned_target */,
b->ctx->cancel_func, b->ctx->cancel_baton,
b->ctx->notify_func2, b->ctx->notify_baton2,
scratch_pool));
Modified: subversion/trunk/subversion/libsvn_wc/adm_ops.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/adm_ops.c?rev=1132834&r1=1132833&r2=1132834&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/trunk/subversion/libsvn_wc/adm_ops.c Mon Jun 6 23:27:06 2011
@@ -593,6 +593,24 @@ erase_unversioned_from_wc(const char *pa
return SVN_NO_ERROR;
}
+/* Delete the file FILE_ABSPATH if it exists. */
+static svn_error_t *
+attempt_deletion(const char *file_abspath,
+ apr_pool_t *scratch_pool)
+{
+ svn_error_t *err;
+
+ if (file_abspath == NULL)
+ return SVN_NO_ERROR;
+
+ err = svn_io_remove_file2(file_abspath, FALSE, scratch_pool);
+
+ if (err == NULL || !APR_STATUS_IS_ENOENT(err->apr_err))
+ return svn_error_return(err);
+
+ svn_error_clear(err);
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_wc_delete4(svn_wc_context_t *wc_ctx,
@@ -609,11 +627,12 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
svn_error_t *err;
svn_wc__db_status_t status;
svn_wc__db_kind_t kind;
+ svn_boolean_t conflicted;
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, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, &conflicted, NULL,
+ NULL, NULL, NULL, NULL, NULL,
db, local_abspath, pool, pool);
if (delete_unversioned_target &&
@@ -662,6 +681,36 @@ svn_wc_delete4(svn_wc_context_t *wc_ctx,
SVN_ERR(svn_wc__write_check(db, svn_dirent_dirname(local_abspath, pool),
pool));
+ if (!keep_local &&
+ conflicted &&
+ kind == svn_wc__db_kind_file)
+ {
+ const apr_array_header_t *conflicts;
+ int i;
+
+ /* Does the file have any unversioned conflict marker files? */
+ SVN_ERR(svn_wc__db_read_conflicts(&conflicts, db, local_abspath,
+ pool, pool));
+
+ for (i = 0; i < conflicts->nelts; i++)
+ {
+ const svn_wc_conflict_description2_t *desc;
+
+ desc = APR_ARRAY_IDX(conflicts, i,
+ const svn_wc_conflict_description2_t*);
+
+ if (desc->kind == svn_wc_conflict_kind_text)
+ {
+ attempt_deletion(desc->base_abspath, pool);
+ attempt_deletion(desc->their_abspath, pool);
+ attempt_deletion(desc->my_abspath, pool);
+ }
+ else if (desc->kind == svn_wc_conflict_kind_property)
+ attempt_deletion(desc->their_abspath, pool);
+ }
+
+ }
+
SVN_ERR(svn_wc__db_op_delete(db, local_abspath,
notify_func, notify_baton,
cancel_func, cancel_baton,
Modified: subversion/trunk/subversion/tests/cmdline/copy_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/copy_tests.py?rev=1132834&r1=1132833&r2=1132834&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/copy_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/copy_tests.py Mon Jun 6 23:27:06
2011
@@ -5222,11 +5222,11 @@ def case_only_rename(sbox):
svntest.actions.run_and_verify_status(wc_dir, expected_status)
@Issue(3899)
-def copying_conflicts(sbox):
- """copying conflicts"""
+def copy_and_move_conflicts(sbox):
+ """copy and move conflicts"""
- # The destination of a copy operation should *not* be conflicted,
- # and should contain the "mine-full" contents.
+ # The destination of a copy or move operation should *not* be
+ # conflicted, and should contain the "mine-full" contents.
sbox.build()
wc = sbox.ospath
@@ -5392,6 +5392,54 @@ def copying_conflicts(sbox):
})
svntest.actions.verify_disk(wc('copy-dest'), expected_disk, True)
+ # Move conflict victims.
+ sbox.simple_move('A/B/E/alpha', 'move-dest')
+ sbox.simple_move('A/D/H', 'move-dest')
+ sbox.simple_move('A/D/G', 'move-dest')
+ sbox.simple_move('A/Q', 'move-dest')
+
+ # Move directories with conflicted children.
+ sbox.simple_move('A/B', 'move-dest')
+ sbox.simple_move('A/D', 'move-dest')
+
+ # Expect same status and disk content as at the copy destination, except
+ # that A/B/E/alpha, A/D/G, and A/D/H were moved away first.
+ expected_status.wc_dir = wc('move-dest')
+ expected_status.tweak('B/E/alpha',
+ 'D/H',
+ 'D/H/chi',
+ 'D/H/omega',
+ 'D/H/psi',
+ status='D ')
+ # A/D/G had been re-added from r4 due to a "local edit, incoming delete"
+ # tree conflict, so moving it away has a different effect.
+ expected_status.remove('D/G',
+ 'D/G/pi',
+ 'D/G/rho',
+ 'D/G/tau')
+ svntest.actions.run_and_verify_status(wc('move-dest'), expected_status)
+
+ expected_disk = svntest.wc.State('', {
+ 'B/E/beta' : Item(contents="This is the file 'beta'.\n"
+ "Edit for merge\n"),
+ 'B/lambda' : Item(contents="This is the file 'lambda'.\n"),
+ 'B/F' : Item(),
+ 'H' : Item(props={'foo':'100'}),
+ 'H/chi' : Item(contents="This is the file 'chi'.\n",
+ props={'foo':'100'}),
+ 'H/psi' : Item(contents="This is the file 'psi'.\n"),
+ 'H/omega' : Item(contents="This is the file 'omega'.\n"),
+ 'D' : Item(),
+ 'G/tau' : Item(contents="This is the file 'tau'.\n"),
+ 'G/rho' : Item(contents="This is the file 'rho'.\n"
+ "Local edit\n"),
+ 'G/pi' : Item(contents="This is the file 'pi'.\n"),
+ 'Q/sigma' : Item(contents="New local file\n"),
+ 'alpha' : Item(contents="This is the file 'alpha'.\n"
+ "Local edit\n"),
+ })
+ svntest.actions.verify_disk(wc('move-dest'), expected_disk, True)
+
########################################################################
# Run the tests
@@ -5501,7 +5549,7 @@ test_list = [ None,
deleted_file_with_case_clash,
copy_base_of_deleted,
case_only_rename,
- copying_conflicts,
+ copy_and_move_conflicts,
]
if __name__ == '__main__':