- for (nlen = -1, blen = 0; value[blen]; blen++)
- if (nlen < 0 && isspace(value[blen]))
- nlen = blen;
- if (nlen < 0)
- return error("%s '%s': lacks command line", var, value);
- fn = xcalloc(1, sizeof(struct user_merge_fn) + blen + 1);
- memcpy(fn->b_, value, blen + 1);
- fn->name = fn->b_;
- fn->b_[nlen] = 0;
- fn->cmdline = fn->b_ + nlen + 1;
- fn->next = *ll_user_merge_fns_tail;
- *ll_user_merge_fns_tail = fn;
+ name = var + 6;
+ namelen = ep - name;
+ for (fn = ll_user_merge; fn; fn = fn->next)
+ if (!strncmp(fn->name, name, namelen) && !fn->name[namelen])
+ break;
+ if (!fn) {
+ char *namebuf;
+ fn = xcalloc(1, sizeof(struct ll_merge_driver));
+ namebuf = xmalloc(namelen + 1);
+ memcpy(namebuf, name, namelen);
+ namebuf[namelen] = 0;
+ fn->name = namebuf;
+ fn->fn = ll_ext_merge;
+ fn->next = *ll_user_merge_tail;
+ *ll_user_merge_tail = fn;
+ }
+
+ ep++;
+
+ if (!strcmp("name", ep)) {
+ if (!value)
+ return error("%s: lacks value", var);
+ fn->description = strdup(value);
+ return 0;
+ }
+
+ if (!strcmp("driver", ep)) {
+ if (!value)
+ return error("%s: lacks value", var);
+ /*
+ * merge.<name>.driver specifies the command line:
+ *
+ * command-line
+ *
+ * The command-line will be interpolated with the following
+ * tokens and is given to the shell:
+ *
+ * %O - temporary file name for the merge base.
+ * %A - temporary file name for our version.
+ * %B - temporary file name for the other branches' version.
+ *
+ * The external merge driver should write the results in the
+ * file named by %A, and signal that it has done with zero exit
+ * status.
+ */
+ fn->cmdline = strdup(value);
+ return 0;
+ }
+