merge-index.con commit fixup tr/stash-format merge (5f809ff)
   1#include "cache.h"
   2#include "run-command.h"
   3#include "exec_cmd.h"
   4
   5static const char *pgm;
   6static int one_shot, quiet;
   7static int err;
   8
   9static int merge_entry(int pos, const char *path)
  10{
  11        int found;
  12        const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
  13        char hexbuf[4][60];
  14        char ownbuf[4][60];
  15
  16        if (pos >= active_nr)
  17                die("git merge-index: %s not in the cache", path);
  18        found = 0;
  19        do {
  20                struct cache_entry *ce = active_cache[pos];
  21                int stage = ce_stage(ce);
  22
  23                if (strcmp(ce->name, path))
  24                        break;
  25                found++;
  26                strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));
  27                sprintf(ownbuf[stage], "%o", ce->ce_mode);
  28                arguments[stage] = hexbuf[stage];
  29                arguments[stage + 4] = ownbuf[stage];
  30        } while (++pos < active_nr);
  31        if (!found)
  32                die("git merge-index: %s not in the cache", path);
  33
  34        if (run_command_v_opt(arguments, 0)) {
  35                if (one_shot)
  36                        err++;
  37                else {
  38                        if (!quiet)
  39                                die("merge program failed");
  40                        exit(1);
  41                }
  42        }
  43        return found;
  44}
  45
  46static void merge_file(const char *path)
  47{
  48        int pos = cache_name_pos(path, strlen(path));
  49
  50        /*
  51         * If it already exists in the cache as stage0, it's
  52         * already merged and there is nothing to do.
  53         */
  54        if (pos < 0)
  55                merge_entry(-pos-1, path);
  56}
  57
  58static void merge_all(void)
  59{
  60        int i;
  61        for (i = 0; i < active_nr; i++) {
  62                struct cache_entry *ce = active_cache[i];
  63                if (!ce_stage(ce))
  64                        continue;
  65                i += merge_entry(i, ce->name)-1;
  66        }
  67}
  68
  69int main(int argc, char **argv)
  70{
  71        int i, force_file = 0;
  72
  73        /* Without this we cannot rely on waitpid() to tell
  74         * what happened to our children.
  75         */
  76        signal(SIGCHLD, SIG_DFL);
  77
  78        if (argc < 3)
  79                usage("git merge-index [-o] [-q] <merge-program> (-a | [--] <filename>*)");
  80
  81        git_extract_argv0_path(argv[0]);
  82
  83        setup_git_directory();
  84        read_cache();
  85
  86        i = 1;
  87        if (!strcmp(argv[i], "-o")) {
  88                one_shot = 1;
  89                i++;
  90        }
  91        if (!strcmp(argv[i], "-q")) {
  92                quiet = 1;
  93                i++;
  94        }
  95        pgm = argv[i++];
  96        for (; i < argc; i++) {
  97                char *arg = argv[i];
  98                if (!force_file && *arg == '-') {
  99                        if (!strcmp(arg, "--")) {
 100                                force_file = 1;
 101                                continue;
 102                        }
 103                        if (!strcmp(arg, "-a")) {
 104                                merge_all();
 105                                continue;
 106                        }
 107                        die("git merge-index: unknown option %s", arg);
 108                }
 109                merge_file(arg);
 110        }
 111        if (err && !quiet)
 112                die("merge program failed");
 113        return err;
 114}