Author: stsp Date: Thu Nov 24 10:51:24 2011 New Revision: 1205784 URL: http://svn.apache.org/viewvc?rev=1205784&view=rev Log: On the moves-scan-log branch, fix support for multiple move suggestions.
* subversion/include/svn_wc.h (svn_wc_conflict_description2_t): Rename suggested_move to suggested_moves and make this an array. This will be useful in case the log scanning heuristic returns multiple move suggestions (which it does not as of yet). * subversion/svn/conflict-callbacks.c (pick_move, svn_cl__conflict_handler): Handle move suggestions array. If only one suggestion is present in the array, use it right away without prompting the user (is this always OK? TBD). * subversion/libsvn_wc/update_editor.c (find_applicable_move): Rename to ... (find_applicable_moves): ... this, and return an array of applicable move chains instead of just one move chain. (delete_entry): Handle move suggestions array. Modified: subversion/branches/moves-scan-log/subversion/include/svn_wc.h subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c Modified: subversion/branches/moves-scan-log/subversion/include/svn_wc.h URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/include/svn_wc.h?rev=1205784&r1=1205783&r2=1205784&view=diff ============================================================================== --- subversion/branches/moves-scan-log/subversion/include/svn_wc.h (original) +++ subversion/branches/moves-scan-log/subversion/include/svn_wc.h Thu Nov 24 10:51:24 2011 @@ -1847,11 +1847,12 @@ typedef struct svn_wc_conflict_descripti /** A chain of one or more suggested moves in case the server sends moves * as copy+delete and the revision log was scanned for server-side moves - * at the user's request. + * at the user's request. Elements of this array are pointers to + * svn_wc_repos_move_info_t structures. * @see svn_wc_conflict_choice_t * @see svn_wc_repos_move_info_t * @since New in 1.8. */ - svn_wc_repos_move_info_t *suggested_move; + apr_array_header_t *suggested_moves; /* Remember to adjust svn_wc__conflict_description2_dup() * if you add new fields to this struct. */ Modified: subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c?rev=1205784&r1=1205783&r2=1205784&view=diff ============================================================================== --- subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c (original) +++ subversion/branches/moves-scan-log/subversion/libsvn_wc/update_editor.c Thu Nov 24 10:51:24 2011 @@ -1807,11 +1807,11 @@ compare_revision_items_ascending(const s } static svn_error_t * -find_applicable_move(svn_wc_repos_move_info_t **move, - struct edit_baton *eb, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool) +find_applicable_moves(apr_array_header_t **moves, + struct edit_baton *eb, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { const char *repos_relpath; svn_revnum_t base_revision; @@ -1819,7 +1819,7 @@ find_applicable_move(svn_wc_repos_move_i svn_boolean_t update_into_past; int i; - *move = NULL; + *moves = apr_array_make(result_pool, 0, sizeof(svn_wc_repos_move_info_t *)); if (! eb->repos_moves || apr_hash_count(eb->repos_moves) == 0) return SVN_NO_ERROR; @@ -1853,7 +1853,7 @@ find_applicable_move(svn_wc_repos_move_i svn_sort__item_t elt = APR_ARRAY_IDX(sorted, i, svn_sort__item_t); const svn_revnum_t *rev = elt.key; - apr_array_header_t *moves = elt.value; + apr_array_header_t *moves_in_rev = elt.value; /* When updating into the future, a move applies if it * happened after the base rev of the node. */ @@ -1866,11 +1866,11 @@ find_applicable_move(svn_wc_repos_move_i * rB: mv b->c * rC: mv c->d * and so on. Find the first applicable move in the chain. */ - for (j = 0; j < moves->nelts; j++) + for (j = 0; j < moves_in_rev->nelts; j++) { svn_wc_repos_move_info_t *this_move; - this_move = APR_ARRAY_IDX(moves, j, + this_move = APR_ARRAY_IDX(moves_in_rev, j, svn_wc_repos_move_info_t *); if (strcmp(this_move->moved_from_repos_relpath, repos_relpath) == 0) @@ -1888,7 +1888,7 @@ find_applicable_move(svn_wc_repos_move_i this_move->revision, this_move->copyfrom_rev, NULL, NULL, result_pool); - *move = m; + APR_ARRAY_PUSH(*moves, svn_wc_repos_move_info_t *) = m; /* Add any further applicable moves to the chain. */ while (this_move->next) { @@ -1918,7 +1918,7 @@ find_applicable_move(svn_wc_repos_move_i svn_sort__item_t elt = APR_ARRAY_IDX(sorted, i, svn_sort__item_t); const svn_revnum_t *rev = elt.key; - apr_array_header_t *moves = elt.value; + apr_array_header_t *moves_in_rev = elt.value; /* When updating into the past, a move applies if it * happened before or at the base rev of the node. */ @@ -1931,11 +1931,11 @@ find_applicable_move(svn_wc_repos_move_i * rB: mv c->b (actually b->c) * rA: mv b->a (actually a->b) * and so on. Find the first applicable move in the chain. */ - for (j = 0; j < moves->nelts; j++) + for (j = 0; j < moves_in_rev->nelts; j++) { svn_wc_repos_move_info_t *this_move; - this_move = APR_ARRAY_IDX(moves, j, + this_move = APR_ARRAY_IDX(moves_in_rev, j, svn_wc_repos_move_info_t *); if (strcmp(this_move->moved_to_repos_relpath, repos_relpath) == 0) @@ -1961,7 +1961,7 @@ find_applicable_move(svn_wc_repos_move_i this_move->revision, this_move->revision, NULL, NULL, result_pool); - *move = m; + APR_ARRAY_PUSH(*moves, svn_wc_repos_move_info_t *) = m; /* Add any further applicable moves to the chain. */ while (this_move->prev) { @@ -2137,17 +2137,15 @@ delete_entry(const char *path, " returned no results")); if (result->choice == svn_wc_conflict_choose_scan_log_for_moves) { - svn_wc_repos_move_info_t *move; - /* Scan revision log for server-side moves */ SVN_ERR(get_repos_moves(eb, scratch_pool)); /* Find a server-side move which applies to the deleted node. */ if (apr_hash_count(eb->repos_moves) > 0) { - SVN_ERR(find_applicable_move(&move, eb, local_abspath, - scratch_pool, scratch_pool)); - tree_conflict->suggested_move = move; + SVN_ERR(find_applicable_moves( + &tree_conflict->suggested_moves, eb, + local_abspath, scratch_pool, scratch_pool)); } continue; } Modified: subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c?rev=1205784&r1=1205783&r2=1205784&view=diff ============================================================================== --- subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c (original) +++ subversion/branches/moves-scan-log/subversion/svn/conflict-callbacks.c Thu Nov 24 10:51:24 2011 @@ -258,18 +258,31 @@ launch_resolver(svn_boolean_t *performed static svn_error_t * pick_move(svn_wc_repos_move_info_t **move, - const svn_wc_conflict_description2_t *desc, + apr_array_header_t *suggested_moves, svn_cmdline_prompt_baton_t *pb, apr_pool_t *scratch_pool) { const char *prompt; - svn_wc_repos_move_info_t *this_move = desc->suggested_move; + svn_wc_repos_move_info_t *this_move; int i = 0; int m; apr_pool_t *iterpool; - prompt = _("Moves found in revision log:\n"); - do + if (suggested_moves->nelts == 1) + { + this_move = APR_ARRAY_IDX(suggested_moves, 0, + svn_wc_repos_move_info_t *); + SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, + _(" [r%ld] %s@%ld -> %s\n"), + this_move->revision, this_move->moved_from_repos_relpath, + this_move->copyfrom_rev, this_move->moved_to_repos_relpath)); + + *move = this_move; + return SVN_NO_ERROR; + } + + prompt = _("Multiple moves found in revision log:\n"); + for (i = 0; i < suggested_moves->nelts; i++) { prompt = apr_pstrcat(scratch_pool, prompt, apr_psprintf(scratch_pool, @@ -279,10 +292,8 @@ pick_move(svn_wc_repos_move_info_t **mov this_move->copyfrom_rev, this_move->moved_to_repos_relpath), (char *)NULL); - i++; this_move = this_move->next; } - while (this_move); prompt = apr_pstrcat(scratch_pool, prompt, _("Enter number to choose incoming move or hit enter " @@ -318,20 +329,14 @@ pick_move(svn_wc_repos_move_info_t **mov return svn_error_trace(err); } - if (m < 0 || m >= i) + if (m < 0 || m >= suggested_moves->nelts) { SVN_ERR(svn_cmdline_fprintf(stderr, iterpool, "Invalid choice (%i)\n", m)); continue; } - *move = desc->suggested_move; - i = 0; - while (m < i && (*move)->next) - { - *move = (*move)->next; - m++; - } + *move = APR_ARRAY_IDX(suggested_moves, m, svn_wc_repos_move_info_t *); } svn_pool_destroy(iterpool); @@ -844,7 +849,7 @@ svn_cl__conflict_handler(svn_wc_conflict const char *answer; const char *prompt; - if (!desc->suggested_move) + if (!desc->suggested_moves) SVN_ERR(svn_cmdline_fprintf( stderr, subpool, _("Tree conflict discovered when trying to delete\n'%s'\n" @@ -859,16 +864,25 @@ svn_cl__conflict_handler(svn_wc_conflict { svn_pool_clear(subpool); - if (desc->suggested_move) + if (desc->suggested_moves) { - svn_wc_repos_move_info_t *move; - - SVN_ERR(pick_move(&move, desc, b->pb, subpool)); - if (move) + if (desc->suggested_moves->nelts == 0) { - (*result)->choice = svn_wc_conflict_choose_incoming_move; - (*result)->incoming_move = move; - break; + SVN_ERR(svn_cmdline_fprintf(stderr, subpool, + _("No moves found in revision log.\n"))); + } + else + { + svn_wc_repos_move_info_t *move; + + SVN_ERR(pick_move(&move, desc->suggested_moves, b->pb, + subpool)); + if (move) + { + (*result)->choice = svn_wc_conflict_choose_incoming_move; + (*result)->incoming_move = move; + break; + } } } @@ -903,8 +917,26 @@ svn_cl__conflict_handler(svn_wc_conflict if (strcmp(answer, "s") == 0) { - if (desc->suggested_move) - continue; + if (desc->suggested_moves) + { + svn_wc_repos_move_info_t *move; + + if (desc->suggested_moves->nelts == 0) + { + SVN_ERR(svn_cmdline_fprintf(stderr, subpool, + _("No moves found in revision log.\n"))); + continue; + } + + SVN_ERR(pick_move(&move, desc->suggested_moves, b->pb, + subpool)); + if (move) + { + (*result)->choice = svn_wc_conflict_choose_incoming_move; + (*result)->incoming_move = move; + break; + } + } else { (*result)->choice = svn_wc_conflict_choose_scan_log_for_moves;