Author: stsp Date: Fri Jul 6 20:19:44 2012 New Revision: 1358401 URL: http://svn.apache.org/viewvc?rev=1358401&view=rev Log: Allow exiting from the interactive file merge tool without having to postpone every conflicting section in the file.
Suggested by: jcorvel * subversion/svn/file-merge.c (file_merge_baton): Add abort_merge member. (file_merge_output_common, file_merge_output_diff_modified, file_merge_output_diff_latest, file_merge_output_diff_common): Do nothing if merge has been aborted. (merge_chunks): Add abort_merge output parameter, and offer the user the option of aborting the entire merge. (merge_file_chunks): Add abort_merge output paramter, pass it through to merge_chunks() and abort the merge if it gets set. (file_merge_output_conflict): Do nothing if merge has been aborted, and pass the abort_merge baton member to merge_file_chunks(). (svn_cl__merge_file): Initialise abort_merge in the file_merge_baton and remove the temporary merged file in case the user aborts the merge. Modified: subversion/trunk/subversion/svn/file-merge.c Modified: subversion/trunk/subversion/svn/file-merge.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/file-merge.c?rev=1358401&r1=1358400&r2=1358401&view=diff ============================================================================== --- subversion/trunk/subversion/svn/file-merge.c (original) +++ subversion/trunk/subversion/svn/file-merge.c Fri Jul 6 20:19:44 2012 @@ -70,6 +70,9 @@ struct file_merge_baton { /* The client configuration hash. */ apr_hash_t *config; + /* Wether the merge should be aborted. */ + svn_boolean_t abort_merge; + /* Pool for temporary allocations. */ apr_pool_t *scratch_pool; } file_merge_baton; @@ -148,6 +151,9 @@ file_merge_output_common(void *output_ba { struct file_merge_baton *b = output_baton; + if (b->abort_merge) + return SVN_NO_ERROR; + SVN_ERR(copy_to_merged_file(&b->current_line_original, b->merged_file, b->original_file, @@ -171,6 +177,9 @@ file_merge_output_diff_modified(void *ou { struct file_merge_baton *b = output_baton; + if (b->abort_merge) + return SVN_NO_ERROR; + SVN_ERR(copy_to_merged_file(&b->current_line_modified, b->merged_file, b->modified_file, @@ -195,6 +204,9 @@ file_merge_output_diff_latest(void *outp { struct file_merge_baton *b = output_baton; + if (b->abort_merge) + return SVN_NO_ERROR; + SVN_ERR(copy_to_merged_file(&b->current_line_latest, b->merged_file, b->latest_file, @@ -219,6 +231,9 @@ file_merge_output_diff_common(void *outp { struct file_merge_baton *b = output_baton; + if (b->abort_merge) + return SVN_NO_ERROR; + SVN_ERR(copy_to_merged_file(&b->current_line_latest, b->merged_file, b->latest_file, @@ -535,9 +550,11 @@ get_sep_string(apr_pool_t *result_pool) /* Merge chunks CHUNK1 and CHUNK2. * Each lines array contains elements of type svn_stringbuf_t*. * Return the result in *MERGED_CHUNK, or set *MERGED_CHUNK to NULL in - * case the user chooses to postpone resolution of this chunk. */ + * case the user chooses to postpone resolution of this chunk. + * If the user wants to abort the merge, set *ABORT_MERGE to TRUE. */ static svn_error_t * merge_chunks(apr_array_header_t **merged_chunk, + svn_boolean_t *abort_merge, apr_array_header_t *chunk1, apr_array_header_t *chunk2, svn_linenum_t current_line1, @@ -554,12 +571,15 @@ merge_chunks(apr_array_header_t **merged max_chunk_lines = chunk1->nelts > chunk2->nelts ? chunk1->nelts : chunk2->nelts; + *abort_merge = FALSE; + /* * Prepare the selection prompt. */ prompt = svn_stringbuf_create( - apr_psprintf(scratch_pool, "%s|%s\n%s", + apr_psprintf(scratch_pool, "%s\n%s|%s\n%s", + _("Conflicting section found during merge."), prepare_line_for_display( apr_psprintf(scratch_pool, _("(1) their version (at line %lu)"), @@ -616,10 +636,12 @@ merge_chunks(apr_array_header_t **merged svn_stringbuf_appendcstr(prompt, get_sep_string(scratch_pool)); svn_stringbuf_appendcstr( prompt, - _("Select: (1) use their version, (2) use your version, (p) postpone,\n" + _("Select: (1) use their version, (2) use your version,\n" " (e1) edit their version and use the result,\n" " (e2) edit your version and use the result,\n" - " (eb) edit both versions and use the result: ")); + " (eb) edit both versions and use the result,\n" + " (p) postpone this conflicting section leaving conflict markers,\n" + " (a) abort entire merge and return to main menu: ")); /* Now let's see what the user wants to do with this conflict. */ while (TRUE) @@ -669,6 +691,11 @@ merge_chunks(apr_array_header_t **merged if (*merged_chunk) break; } + else if (strcmp(answer, "a") == 0) + { + *abort_merge = TRUE; + break; + } } svn_pool_destroy(iterpool); @@ -678,9 +705,11 @@ merge_chunks(apr_array_header_t **merged /* Perform a merge of chunks from FILE1 and FILE2, specified by START1/LEN1 * and START2/LEN2, respectively. Append the result to MERGED_FILE. * The current line numbers for FILE1 and FILE2 are passed in *CURRENT_LINE1 - * and *CURRENT_LINE2, and will be updated to new values upon return. */ + * and *CURRENT_LINE2, and will be updated to new values upon return. + * If the user wants to abort the merge, set *ABORT_MERGE to TRUE. */ static svn_error_t * merge_file_chunks(svn_boolean_t *remains_in_conflict, + svn_boolean_t *abort_merge, apr_file_t *merged_file, apr_file_t *file1, apr_file_t *file2, @@ -705,11 +734,14 @@ merge_file_chunks(svn_boolean_t *remains SVN_ERR(read_diff_chunk(&chunk2, current_line2, file2, *current_line2, start2, len2, scratch_pool, scratch_pool)); - SVN_ERR(merge_chunks(&merged_chunk, chunk1, chunk2, + SVN_ERR(merge_chunks(&merged_chunk, abort_merge, chunk1, chunk2, *current_line1, *current_line2, editor_cmd, config, scratch_pool, scratch_pool)); + if (*abort_merge) + return SVN_NO_ERROR; + /* If the user chose 'postpone' put conflict markers and left/right * versions into the merged file. */ if (merged_chunk == NULL) @@ -753,7 +785,11 @@ file_merge_output_conflict(void *output_ { struct file_merge_baton *b = output_baton; + if (b->abort_merge) + return SVN_NO_ERROR; + SVN_ERR(merge_file_chunks(&b->remains_in_conflict, + &b->abort_merge, b->merged_file, b->modified_file, b->latest_file, @@ -825,6 +861,7 @@ svn_cl__merge_file(const char *base_path fmb.remains_in_conflict = FALSE; fmb.editor_cmd = editor_cmd; fmb.config = config; + fmb.abort_merge = FALSE; fmb.scratch_pool = scratch_pool; SVN_ERR(svn_diff_output(diff, &fmb, &file_merge_diff_output_fns)); @@ -835,7 +872,13 @@ svn_cl__merge_file(const char *base_path SVN_ERR(svn_io_file_close(merged_file, scratch_pool)); if (remains_in_conflict) - *remains_in_conflict = fmb.remains_in_conflict; + *remains_in_conflict = (fmb.remains_in_conflict || fmb.abort_merge); + + if (fmb.abort_merge) + { + SVN_ERR(svn_io_remove_file2(merged_file_name, TRUE, scratch_pool)); + return SVN_NO_ERROR; + } SVN_ERR_W(svn_io_file_move(merged_file_name, merged_path, scratch_pool), apr_psprintf(scratch_pool,