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