From: Andreas Gruenbacher Subject: diff3-style merges: merge rejects With the --merge-all option, hunks which do not apply and which would end up in a *.rej file will also get added to output files. They will be bracketed like this: <<<<<<< old lines from patch ||||||| new lines from patch >>>>>>> With this change, all pieces of a patch can be applied, and all the resulting merge conflicts can be fixed in the patched files instead of looking at the reject files. Signed-off-by: Andreas Gruenbacher --- patch.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) Index: b/patch.c =================================================================== --- a/patch.c +++ b/patch.c @@ -79,7 +79,7 @@ static void reinitialize_almost_everythi static void remove_if_needed (char const *, int volatile *); static void usage (FILE *, int) __attribute__((noreturn)); -enum mergetype { SHOW_ALL = 1, SHOW_FUZZ = 2 }; +enum mergetype { SHOW_ALL = 1, SHOW_FUZZ = 2, MERGE_REJECTS = 4 }; static enum mergetype mergetype; static bool make_backups; @@ -299,7 +299,18 @@ main (int argc, char **argv) goto skip_hunk; } else if (!where) { - goto skip_hunk; + if (mergetype & MERGE_REJECTS) { + LINENUM guess = pch_first () + last_offset; + + if (merge_hunk(&outstate, guess, -1)) { + merged++; + mismatch = 1; + } else { + /* FIXME: guess harder! */ + goto skip_hunk; + } + } else + goto skip_hunk; } else { if ((mergetype & SHOW_ALL) || (fuzz && (mergetype & SHOW_FUZZ))) { @@ -316,10 +327,16 @@ main (int argc, char **argv) if (verbosity == VERBOSE || (verbosity != SILENT && (fuzz || last_offset))) { - say ("Hunk #%d succeeded at %s", hunk, - format_linenum (numbuf, newwhere)); - if (fuzz) - say (" with fuzz %s", format_linenum (numbuf, fuzz)); + if (fuzz > mymaxfuzz) { + say ("Hunk #%d merged at %s with errors", hunk, + format_linenum (numbuf, newwhere)); + somefailed = true; + } else { + say ("Hunk #%d succeeded at %s", hunk, + format_linenum (numbuf, newwhere)); + if (fuzz) + say (" with fuzz %s", format_linenum (numbuf, fuzz)); + } if (last_offset) say (" (offset %s line%s)", format_linenum (numbuf, last_offset), @@ -521,7 +538,7 @@ reinitialize_almost_everything (void) skip_rest_of_patch = false; } -static char const shortopts[] = "bB:cd:D:eEfF:g:i:lnNo:p:r:RstTuvV:x:Y:z:Z"; +static char const shortopts[] = "bB:cd:D:eEfF:g:i:lMnNo:p:r:RstTuvV:x:Y:z:Z"; static struct option const longopts[] = { {"backup", no_argument, NULL, 'b'}, @@ -591,7 +608,7 @@ static char const *const option_help[] = " -r FILE --reject-file=FILE Output rejects to FILE.", "", " -D NAME --ifdef=NAME Make merged if-then-else output using NAME.", -" --merge={fuzz,all} Produce a diff3-style merge.", +" --merge={rejects,fuzz,all} Produce a diff3-style merge.", " -E --remove-empty-files Remove output files that are empty after patching.", "", " -Z --set-utc Set times of patched files, assuming diff uses UTC (GMT).", @@ -730,6 +747,9 @@ get_some_switches (void) case 'l': canonicalize = true; break; + case 'M': + mergetype |= MERGE_REJECTS; + break; case 'n': diff_type = NORMAL_DIFF; break; @@ -835,7 +855,9 @@ get_some_switches (void) char *tok = strtok(optarg, ","); do { - if (!strcmp(tok, "fuzz")) + if (!strcmp(tok, "rejects")) + mergetype |= MERGE_REJECTS; + else if (!strcmp(tok, "fuzz")) mergetype |= SHOW_FUZZ; else if (!strcmp(tok, "all")) mergetype |= SHOW_ALL;