]>
Commit | Line | Data |
---|---|---|
1 | #include "cache.h" | |
2 | #include "run-command.h" | |
3 | #include "exec_cmd.h" | |
4 | ||
5 | static const char *pgm; | |
6 | static int one_shot, quiet; | |
7 | static int err; | |
8 | ||
9 | static 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 | ||
46 | static 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 | ||
58 | static 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 | ||
69 | int cmd_merge_index(int argc, const char **argv, const char *prefix) | |
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 | read_cache(); | |
82 | ||
83 | i = 1; | |
84 | if (!strcmp(argv[i], "-o")) { | |
85 | one_shot = 1; | |
86 | i++; | |
87 | } | |
88 | if (!strcmp(argv[i], "-q")) { | |
89 | quiet = 1; | |
90 | i++; | |
91 | } | |
92 | pgm = argv[i++]; | |
93 | for (; i < argc; i++) { | |
94 | const char *arg = argv[i]; | |
95 | if (!force_file && *arg == '-') { | |
96 | if (!strcmp(arg, "--")) { | |
97 | force_file = 1; | |
98 | continue; | |
99 | } | |
100 | if (!strcmp(arg, "-a")) { | |
101 | merge_all(); | |
102 | continue; | |
103 | } | |
104 | die("git merge-index: unknown option %s", arg); | |
105 | } | |
106 | merge_file(arg); | |
107 | } | |
108 | if (err && !quiet) | |
109 | die("merge program failed"); | |
110 | return err; | |
111 | } |