SHA256
3
0
forked from pool/patch
patch/diff3-style-merges-rejects.diff

117 lines
3.6 KiB
Diff

From: Andreas Gruenbacher <agruen@suse.de>
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 <agruen@suse.de>
---
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;