Author: stsp Date: Mon Feb 25 14:46:27 2013 New Revision: 1449727 URL: http://svn.apache.org/r1449727 Log: For a incoming-edit vs. local-delete tree conflict, where the locally deleted subtree has moved-away children, make 'svn resolve --accept working' break moves without updating any moved-away nodes, and make 'svn resolve --accept mine-conflict' flag incoming edit vs. local-move conflicts on moved-away children. The moved-away children can then be updated by resolving them with 'mine-conflict' as well.
Previously, '--accept working' behaved like '--accept mine-conflict' does now. Users can now accept the current working copy state (where moved-away nodes are at a different revision than the move source) with --accept working. This will break moves and remove conflict markers, but otherwise leave the working copy unchanged. And most importantly it will not raise new conflicts in the working copy. Raising new conflicts while resolving to the 'current working copy state' is at odds with how this operation used to behave in Subversion 1.7 and older. Discussed with: philip http://colabti.org/irclogger/irclogger_log/svn-dev?date=2013-02-25#l48 * subversion/libsvn_wc/conflicts.c (resolve_tree_conflict_on_node): Break moves for moved-away children in deleted subtrees when resolution choice is 'merged'. If the choice is 'mine_conflict' then raise edit vs. moved-away conflicts on moved-away children within the deleted subtree. * subversion/libsvn_wc/wc_db.h (svn_wc__db_resolve_break_moved_away_children): Declare. * subversion/libsvn_wc/wc_db_update_move.c (break_move): New helper function, split out of ... (svn_wc__db_resolve_break_moved_away_internal): ... this function, which is otherwise unchanged. (break_moved_away_children_internal): New function. Uses the break_move() helper to break moves on moved-away children of a given node. (svn_wc__db_resolve_break_moved_away_children): New. A wrapper around break_moved_away_children_internal() to make it transaction-safe. * subversion/tests/libsvn_wc/op-depth-test.c (move_in_delete, layered_moved_to): Use 'mine_conflict' where the previous 'resolution-to-working' behaviour is expected. Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c subversion/trunk/subversion/libsvn_wc/wc_db.h subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Modified: subversion/trunk/subversion/libsvn_wc/conflicts.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/conflicts.c?rev=1449727&r1=1449726&r2=1449727&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/conflicts.c (original) +++ subversion/trunk/subversion/libsvn_wc/conflicts.c Mon Feb 25 14:46:27 2013 @@ -2668,6 +2668,19 @@ resolve_tree_conflict_on_node(svn_skel_t { if (conflict_choice == svn_wc_conflict_choose_merged) { + /* Break moves for any children moved out of this directory, + * and leave this directory deleted. */ + SVN_ERR(svn_wc__db_resolve_break_moved_away_children( + db, local_abspath, scratch_pool)); + did_resolve = TRUE; + } + + if (conflict_choice == svn_wc_conflict_choose_mine_conflict) + { + /* Raised moved-away conflicts on any children moved out of + * this directory, and leave this directory deleted. + * The newly conflicted moved-away children will be updated + * if they are resolved with 'mine_conflict' as well. */ SVN_ERR(svn_wc__db_resolve_delete_raise_moved_away( db, local_abspath, notify_func, notify_baton, scratch_pool)); Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=1449727&r1=1449726&r2=1449727&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/wc_db.h (original) +++ subversion/trunk/subversion/libsvn_wc/wc_db.h Mon Feb 25 14:46:27 2013 @@ -3352,6 +3352,16 @@ svn_error_t * svn_wc__db_resolve_break_moved_away(svn_wc__db_t *db, const char *local_abspath, apr_pool_t *scratch_pool); + +/* Break moves for all moved-away children of LOCAL_ABSPATH, within + * a single transaction. + * + * ### Like svn_wc__db_resolve_delete_raise_moved_away this should be + * combined. */ +svn_error_t * +svn_wc__db_resolve_break_moved_away_children(svn_wc__db_t *db, + const char *local_abspath, + apr_pool_t *scratch_pool); /* @} */ Modified: subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c?rev=1449727&r1=1449726&r2=1449727&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c (original) +++ subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c Mon Feb 25 14:46:27 2013 @@ -2343,6 +2343,32 @@ svn_wc__db_resolve_delete_raise_moved_aw return SVN_NO_ERROR; } +static svn_error_t * +break_move(svn_wc__db_wcroot_t *wcroot, + const char *src_relpath, + int src_op_depth, + const char *dst_relpath, + int dst_op_depth, + apr_pool_t *scratch_pool) +{ + svn_sqlite__stmt_t *stmt; + + SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, + STMT_CLEAR_MOVED_TO_RELPATH)); + SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, src_relpath, + src_op_depth)); + SVN_ERR(svn_sqlite__step_done(stmt)); + + /* This statement clears moved_here. */ + SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, + STMT_UPDATE_OP_DEPTH_RECURSIVE)); + SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id, + dst_relpath, dst_op_depth, dst_op_depth)); + SVN_ERR(svn_sqlite__step_done(stmt)); + + return SVN_NO_ERROR; +} + svn_error_t * svn_wc__db_resolve_break_moved_away_internal(svn_wc__db_wcroot_t *wcroot, const char *local_relpath, @@ -2350,8 +2376,6 @@ svn_wc__db_resolve_break_moved_away_inte { const char *dummy1, *move_dst_op_root_relpath; const char *dummy2, *move_src_op_root_relpath; - svn_sqlite__stmt_t *stmt; - int dst_op_depth; SVN_ERR(svn_wc__db_op_depth_moved_to(&dummy1, &move_dst_op_root_relpath, &dummy2, @@ -2359,21 +2383,45 @@ svn_wc__db_resolve_break_moved_away_inte relpath_depth(local_relpath) - 1, wcroot, local_relpath, scratch_pool, scratch_pool)); - dst_op_depth = relpath_depth(move_dst_op_root_relpath); + SVN_ERR(break_move(wcroot, local_relpath, + relpath_depth(move_src_op_root_relpath), + move_dst_op_root_relpath, + relpath_depth(move_dst_op_root_relpath), + scratch_pool)); - SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, - STMT_CLEAR_MOVED_TO_RELPATH)); - SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath, - relpath_depth(move_src_op_root_relpath))); - SVN_ERR(svn_sqlite__step_done(stmt)); + return SVN_NO_ERROR; +} + +static svn_error_t * +break_moved_away_children_internal(svn_wc__db_wcroot_t *wcroot, + const char *local_relpath, + apr_pool_t *scratch_pool) +{ + svn_sqlite__stmt_t *stmt; + svn_boolean_t have_row; + apr_pool_t *iterpool; - /* This statement clears moved_here. */ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, - STMT_UPDATE_OP_DEPTH_RECURSIVE)); - SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id, - move_dst_op_root_relpath, - dst_op_depth, dst_op_depth)); - SVN_ERR(svn_sqlite__step_done(stmt)); + STMT_SELECT_MOVED_PAIR2)); + SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath)); + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + + iterpool = svn_pool_create(scratch_pool); + while (have_row) + { + const char *src_relpath = svn_sqlite__column_text(stmt, 0, iterpool); + const char *dst_relpath = svn_sqlite__column_text(stmt, 1, iterpool); + int src_op_depth = svn_sqlite__column_int(stmt, 2); + + svn_pool_clear(iterpool); + + SVN_ERR(break_move(wcroot, src_relpath, src_op_depth, dst_relpath, + relpath_depth(dst_relpath), iterpool)); + SVN_ERR(svn_sqlite__step(&have_row, stmt)); + } + svn_pool_destroy(iterpool); + + SVN_ERR(svn_sqlite__reset(stmt)); return SVN_NO_ERROR; } @@ -2398,3 +2446,23 @@ svn_wc__db_resolve_break_moved_away(svn_ return SVN_NO_ERROR; } + +svn_error_t * +svn_wc__db_resolve_break_moved_away_children(svn_wc__db_t *db, + const char *local_abspath, + apr_pool_t *scratch_pool) +{ + svn_wc__db_wcroot_t *wcroot; + const char *local_relpath; + + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, + db, local_abspath, + scratch_pool, scratch_pool)); + VERIFY_USABLE_WCROOT(wcroot); + + SVN_WC__DB_WITH_TXN( + break_moved_away_children_internal(wcroot, local_relpath, scratch_pool), + wcroot); + + return SVN_NO_ERROR; +} Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1449727&r1=1449726&r2=1449727&view=diff ============================================================================== --- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original) +++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Mon Feb 25 14:46:27 2013 @@ -5906,7 +5906,7 @@ move_in_delete(const svn_test_opts_t *op SVN_ERR(sbox_wc_update(&b, "", 2)); SVN_ERR(sbox_wc_resolve(&b, "A/B", svn_depth_empty, - svn_wc_conflict_choose_merged)); + svn_wc_conflict_choose_mine_conflict)); SVN_ERR(sbox_wc_resolve(&b, "A/B/C", svn_depth_empty, svn_wc_conflict_choose_mine_conflict)); { @@ -6232,7 +6232,7 @@ layered_moved_to(const svn_test_opts_t * SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty, svn_wc_conflict_choose_mine_conflict)); SVN_ERR(sbox_wc_resolve(&b, "X/B/C", svn_depth_empty, - svn_wc_conflict_choose_merged)); + svn_wc_conflict_choose_mine_conflict)); SVN_ERR(sbox_wc_resolve(&b, "X/B/C/D/E", svn_depth_empty, svn_wc_conflict_choose_mine_conflict)); { @@ -6389,7 +6389,7 @@ layered_moved_to(const svn_test_opts_t * SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty, svn_wc_conflict_choose_mine_conflict)); SVN_ERR(sbox_wc_resolve(&b, "X/B/C", svn_depth_empty, - svn_wc_conflict_choose_merged)); + svn_wc_conflict_choose_mine_conflict)); /* Cannot resolve C */ err = sbox_wc_resolve(&b, "C", svn_depth_empty,
