1#include "cache.h"2#include "run-command.h"34static const char *pgm;5static const char *arguments[8];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] = "";39found = 0;40do {41static char hexbuf[4][60];42static char ownbuf[4][60];43struct cache_entry *ce = active_cache[pos];44int stage = ce_stage(ce);4546if (strcmp(ce->name, path))47break;48found++;49strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));50sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode));51arguments[stage] = hexbuf[stage];52arguments[stage + 4] = ownbuf[stage];53} while (++pos < active_nr);54if (!found)55die("git-merge-index: %s not in the cache", path);56run_program();57return found;58}5960static void merge_file(const char *path)61{62int pos = cache_name_pos(path, strlen(path));6364/*65* If it already exists in the cache as stage0, it's66* already merged and there is nothing to do.67*/68if (pos < 0)69merge_entry(-pos-1, path);70}7172static void merge_all(void)73{74int i;75for (i = 0; i < active_nr; i++) {76struct cache_entry *ce = active_cache[i];77if (!ce_stage(ce))78continue;79i += merge_entry(i, ce->name)-1;80}81}8283int main(int argc, char **argv)84{85int i, force_file = 0;8687/* Without this we cannot rely on waitpid() to tell88* what happened to our children.89*/90signal(SIGCHLD, SIG_DFL);9192if (argc < 3)93usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)");9495setup_git_directory();96read_cache();9798i = 1;99if (!strcmp(argv[i], "-o")) {100one_shot = 1;101i++;102}103if (!strcmp(argv[i], "-q")) {104quiet = 1;105i++;106}107pgm = argv[i++];108for (; i < argc; i++) {109char *arg = argv[i];110if (!force_file && *arg == '-') {111if (!strcmp(arg, "--")) {112force_file = 1;113continue;114}115if (!strcmp(arg, "-a")) {116merge_all();117continue;118}119die("git-merge-index: unknown option %s", arg);120}121merge_file(arg);122}123if (err && !quiet)124die("merge program failed");125return err;126}