1#include "cache.h"2#include "run-command.h"34static const char *pgm;5static const char *arguments[9];6static int one_shot, quiet;7static int err;89static void run_program(void)10{11struct child_process child;12memset(&child, 0, sizeof(child));13child.argv = arguments;14if (run_command(&child)) {15if (one_shot) {16err++;17} else {18if (!quiet)19die("merge program failed");20exit(1);21}22}23}2425static int merge_entry(int pos, const char *path)26{27int found;2829if (pos >= active_nr)30die("git merge-index: %s not in the cache", path);31arguments[0] = pgm;32arguments[1] = "";33arguments[2] = "";34arguments[3] = "";35arguments[4] = path;36arguments[5] = "";37arguments[6] = "";38arguments[7] = "";39arguments[8] = NULL;40found = 0;41do {42static char hexbuf[4][60];43static char ownbuf[4][60];44struct cache_entry *ce = active_cache[pos];45int stage = ce_stage(ce);4647if (strcmp(ce->name, path))48break;49found++;50strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));51sprintf(ownbuf[stage], "%o", ce->ce_mode);52arguments[stage] = hexbuf[stage];53arguments[stage + 4] = ownbuf[stage];54} while (++pos < active_nr);55if (!found)56die("git merge-index: %s not in the cache", path);57run_program();58return found;59}6061static void merge_file(const char *path)62{63int pos = cache_name_pos(path, strlen(path));6465/*66* If it already exists in the cache as stage0, it's67* already merged and there is nothing to do.68*/69if (pos < 0)70merge_entry(-pos-1, path);71}7273static void merge_all(void)74{75int i;76for (i = 0; i < active_nr; i++) {77struct cache_entry *ce = active_cache[i];78if (!ce_stage(ce))79continue;80i += merge_entry(i, ce->name)-1;81}82}8384int main(int argc, char **argv)85{86int i, force_file = 0;8788/* Without this we cannot rely on waitpid() to tell89* what happened to our children.90*/91signal(SIGCHLD, SIG_DFL);9293if (argc < 3)94usage("git-merge-index [-o] [-q] <merge-program> (-a | [--] <filename>*)");9596setup_git_directory();97read_cache();9899i = 1;100if (!strcmp(argv[i], "-o")) {101one_shot = 1;102i++;103}104if (!strcmp(argv[i], "-q")) {105quiet = 1;106i++;107}108pgm = argv[i++];109for (; i < argc; i++) {110char *arg = argv[i];111if (!force_file && *arg == '-') {112if (!strcmp(arg, "--")) {113force_file = 1;114continue;115}116if (!strcmp(arg, "-a")) {117merge_all();118continue;119}120die("git merge-index: unknown option %s", arg);121}122merge_file(arg);123}124if (err && !quiet)125die("merge program failed");126return err;127}