char Version[] = "wiggle " VERSION " " VERS_DATE " GPL-2+ http://neil.brown.name/wiggle/\n";
-char short_options[] = "xdmwlrhiW123p::VRvqBb";
+char short_options[] = "xdmwlrho:iW123p::VRvqBb";
struct option long_options[] = {
{"browse", 0, 0, 'B'},
{"verbose", 0, 0, 'v'},
{"quiet", 0, 0, 'q'},
{"strip", 1, 0, 'p'},
+ {"output", 1, 0, 'o'},
{"no-ignore", 0, 0, 'i'},
{"show-wiggles",0, 0, 'W'},
{"ignore-blanks",0,0, 'b'},
}
pl = npl;
}
+ memset(&pl[n], 0, sizeof(pl[n]));
pl[n].file = file;
pl[n].start = start;
pl[n].end = end;
pl[n].last = pl[n].next = pl[n].prev = pl[n].parent = -1;
- pl[n].chunks = pl[n].wiggles = 0; pl[n].conflicts = 100;
+ pl[n].conflicts = 100;
pl[n].open = 1;
- pl[n].calced = 0;
- pl[n].is_merge = 0;
*np = n+1;
return pl;
}
ci.merger, 0, &p->wiggles);
p->chunks = p->conflicts;
save_merge(fm, fb, fa, ci.merger,
- p->file, !p->is_merge);
+ p->outfile ?: p->file,
+ p->outfile ? 0 : !p->is_merge);
}
if (!just_diff)
free(sm.body);
static int show_merge(char *origname, FILE *patch, int reverse,
int is_merge, char *before, char *after,
- int replace, int selftest, int ignore_blanks,
+ int replace, char *outfile,
+ int selftest, int ignore_blanks,
int just_diff)
{
- struct plist p;
+ struct plist p = {0};
p.file = origname;
+ if (replace)
+ p.outfile = outfile;
if (patch) {
p.start = 0;
fseek(patch, 0, SEEK_END);
}
int vpatch(int argc, char *argv[], int patch, int strip,
- int reverse, int replace, int selftest, int ignore_blanks)
+ int reverse, int replace, char *outfilename,
+ int selftest, int ignore_blanks)
{
/* NOTE argv[0] is first arg...
* Behaviour depends on number of args and 'patch'.
char *origname = strdup(argv[0]);
origname[strlen(origname) - 4] = '\0';
show_merge(origname, f, reverse, 0, NULL, NULL,
- replace, selftest, ignore_blanks, just_diff);
+ replace, outfilename,
+ selftest, ignore_blanks, just_diff);
} else
show_merge(argv[0], f, reverse, 1, NULL, NULL,
- replace, selftest, ignore_blanks, just_diff);
+ replace, outfilename,
+ selftest, ignore_blanks, just_diff);
break;
case 2: /* an orig and a diff/.rej or two files */
if (just_diff) {
show_merge(NULL, NULL, reverse, 0, argv[0], argv[1],
- replace, selftest, ignore_blanks, just_diff);
+ replace, outfilename,
+ selftest, ignore_blanks, just_diff);
break;
}
f = fopen(argv[1], "r");
exit(1);
}
show_merge(argv[0], f, reverse, 0, NULL, NULL,
- replace, selftest, ignore_blanks, just_diff);
+ replace, outfilename,
+ selftest, ignore_blanks, just_diff);
break;
case 3: /* orig, before, after */
show_merge(argv[0], NULL, reverse, 0, argv[1], argv[2],
- replace, selftest, ignore_blanks, just_diff);
+ replace, outfilename,
+ selftest, ignore_blanks, just_diff);
break;
}
.I wiggle
to always save the resulting merge when exiting.
+.TP
+.BR \-o ", " \-\-output=
+Rather than writing the result to stdout or to replace the original
+file, this requests that the output be written to the given file.
+This is only meaningful with
+.B \-\-merge
+or
+.B \-\-browse
+when given a single merge to browse.
+
+This option overrides
+.BR \-r .
+
.TP
.BR -R ", " \-\-reverse
When used with the
tool = wiggle
[mergetool "wiggle"]
path = /usr/bin/wiggle
- cmd = wiggle \-Br $LOCAL $BASE $REMOTE
+ cmd = wiggle \-B -o $MERGED $LOCAL $BASE $REMOTE
.fi
.RE
}
static int do_merge(int argc, char *argv[], int obj, int blanks,
- int reverse, int replace, int ignore, int show_wiggles,
+ int reverse, int replace, char *outfilename,
+ int ignore, int show_wiggles,
int quiet)
{
/* merge three files, A B C, so changed between B and C get made to A
return 2;
}
}
- if (replace) {
+ if (outfilename) {
+ outfile = fopen(outfilename, "w");
+ if (!outfile) {
+ fprintf(stderr, "%s: could not create %s\n",
+ Cmd, outfilename);
+ return 2;
+ }
+ } else if (replace) {
int fd;
replacename = xmalloc(strlen(argv[0]) + 20);
orignew = xmalloc(strlen(argv[0]) + 20);
ci.ignored,
ci.ignored == 1 ? "" : "s");
- if (replace) {
+ if (outfilename)
+ fclose(outfile);
+ else if (replace) {
fclose(outfile);
if (rename(argv[0], orignew) == 0 &&
rename(replacename, argv[0]) == 0)
pl[i].start, pl[i].end, filename);
av[0] = pl[i].file;
av[1] = name;
- rv |= do_merge(2, av, obj, blanks, reverse, 1, ignore,
+ rv |= do_merge(2, av, obj, blanks, reverse, 1, NULL, ignore,
show_wiggles, quiet);
}
return rv;
int show_wiggles = 0;
char *helpmsg;
char *trace;
+ char *outfile = NULL;
int selftest = 0;
int ignore_blanks = 0;
case 'r':
replace = 1;
continue;
+ case 'o':
+ outfile = optarg;
+ replace = 1;
+ continue;
case 'R':
reverse = 1;
continue;
if (mode == 'B') {
vpatch(argc-optind, argv+optind, ispatch,
- strip, reverse, replace, selftest,
+ strip, reverse, replace, outfile, selftest,
ignore_blanks);
/* should not return */
exit(1);
}
if (mode != 'm' && !obj)
obj = 'w';
+ if (ispatch && outfile) {
+ fprintf(stderr, "%s: --output incompatible with --patch\n",
+ Cmd);
+ exit(2);
+ }
if (replace && mode != 'm') {
fprintf(stderr,
- "%s: --replace only allowed with --merge\n", Cmd);
+ "%s: --replace or --output only allowed with --merge\n", Cmd);
exit(2);
}
if (mode == 'x' && !which) {
exit_status = do_merge(
argc-optind, argv+optind,
obj, ignore_blanks, reverse, replace,
+ outfile,
ignore, show_wiggles, quiet);
break;
}
* as a directory-tree.
*/
struct plist {
- char *file;
+ char *file, *outfile;
unsigned int start, end;
int parent;
int next, prev, last;
extern int do_trace;
extern int vpatch(int argc, char *argv[], int patch, int strip,
- int reverse, int replace, int selftest,
+ int reverse, int replace, char *outfile,
+ int selftest,
int ignore_blanks);
extern char *Cmd;