]>
Commit | Line | Data |
---|---|---|
75118b13 LT |
1 | #include <sys/types.h> |
2 | #include <sys/wait.h> | |
e898081d | 3 | #include <signal.h> |
75118b13 LT |
4 | |
5 | #include "cache.h" | |
6 | ||
96f1e58f | 7 | static const char *pgm; |
e2b6a9d0 | 8 | static const char *arguments[8]; |
bbd14cb0 | 9 | static int one_shot, quiet; |
8c59926f | 10 | static int err; |
75118b13 LT |
11 | |
12 | static void run_program(void) | |
13 | { | |
6f002f98 DR |
14 | pid_t pid = fork(); |
15 | int status; | |
75118b13 LT |
16 | |
17 | if (pid < 0) | |
18 | die("unable to fork"); | |
19 | if (!pid) { | |
20 | execlp(pgm, arguments[0], | |
21 | arguments[1], | |
22 | arguments[2], | |
23 | arguments[3], | |
24 | arguments[4], | |
e2b6a9d0 JB |
25 | arguments[5], |
26 | arguments[6], | |
27 | arguments[7], | |
75118b13 LT |
28 | NULL); |
29 | die("unable to execute '%s'", pgm); | |
30 | } | |
2a459251 | 31 | if (waitpid(pid, &status, 0) < 0 || !WIFEXITED(status) || WEXITSTATUS(status)) { |
bbd14cb0 | 32 | if (one_shot) { |
2a459251 | 33 | err++; |
bbd14cb0 | 34 | } else { |
b32e986c | 35 | if (!quiet) |
bbd14cb0 PB |
36 | die("merge program failed"); |
37 | exit(1); | |
38 | } | |
2a459251 | 39 | } |
75118b13 LT |
40 | } |
41 | ||
75118b13 LT |
42 | static int merge_entry(int pos, const char *path) |
43 | { | |
44 | int found; | |
45 | ||
46 | if (pos >= active_nr) | |
215a7ad1 | 47 | die("git-merge-index: %s not in the cache", path); |
75118b13 LT |
48 | arguments[0] = pgm; |
49 | arguments[1] = ""; | |
50 | arguments[2] = ""; | |
51 | arguments[3] = ""; | |
52 | arguments[4] = path; | |
e2b6a9d0 JB |
53 | arguments[5] = ""; |
54 | arguments[6] = ""; | |
55 | arguments[7] = ""; | |
75118b13 LT |
56 | found = 0; |
57 | do { | |
e3b4be7f | 58 | static char hexbuf[4][60]; |
e2b6a9d0 | 59 | static char ownbuf[4][60]; |
75118b13 LT |
60 | struct cache_entry *ce = active_cache[pos]; |
61 | int stage = ce_stage(ce); | |
62 | ||
63 | if (strcmp(ce->name, path)) | |
64 | break; | |
65 | found++; | |
e3b4be7f | 66 | strcpy(hexbuf[stage], sha1_to_hex(ce->sha1)); |
e2b6a9d0 | 67 | sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode) & (~S_IFMT)); |
e3b4be7f | 68 | arguments[stage] = hexbuf[stage]; |
e2b6a9d0 | 69 | arguments[stage + 4] = ownbuf[stage]; |
75118b13 LT |
70 | } while (++pos < active_nr); |
71 | if (!found) | |
215a7ad1 | 72 | die("git-merge-index: %s not in the cache", path); |
75118b13 LT |
73 | run_program(); |
74 | return found; | |
75 | } | |
76 | ||
77 | static void merge_file(const char *path) | |
78 | { | |
79 | int pos = cache_name_pos(path, strlen(path)); | |
80 | ||
81 | /* | |
82 | * If it already exists in the cache as stage0, it's | |
83 | * already merged and there is nothing to do. | |
84 | */ | |
85 | if (pos < 0) | |
86 | merge_entry(-pos-1, path); | |
87 | } | |
88 | ||
89 | static void merge_all(void) | |
90 | { | |
91 | int i; | |
92 | for (i = 0; i < active_nr; i++) { | |
93 | struct cache_entry *ce = active_cache[i]; | |
94 | if (!ce_stage(ce)) | |
95 | continue; | |
96 | i += merge_entry(i, ce->name)-1; | |
97 | } | |
98 | } | |
99 | ||
100 | int main(int argc, char **argv) | |
101 | { | |
102 | int i, force_file = 0; | |
103 | ||
f0b7367c JH |
104 | /* Without this we cannot rely on waitpid() to tell |
105 | * what happened to our children. | |
106 | */ | |
107 | signal(SIGCHLD, SIG_DFL); | |
108 | ||
75118b13 | 109 | if (argc < 3) |
215a7ad1 | 110 | usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)"); |
75118b13 | 111 | |
53228a5f | 112 | setup_git_directory(); |
75118b13 LT |
113 | read_cache(); |
114 | ||
2a459251 | 115 | i = 1; |
bbd14cb0 | 116 | if (!strcmp(argv[i], "-o")) { |
2a459251 PB |
117 | one_shot = 1; |
118 | i++; | |
119 | } | |
bbd14cb0 PB |
120 | if (!strcmp(argv[i], "-q")) { |
121 | quiet = 1; | |
122 | i++; | |
123 | } | |
2a459251 PB |
124 | pgm = argv[i++]; |
125 | for (; i < argc; i++) { | |
75118b13 LT |
126 | char *arg = argv[i]; |
127 | if (!force_file && *arg == '-') { | |
128 | if (!strcmp(arg, "--")) { | |
129 | force_file = 1; | |
130 | continue; | |
131 | } | |
132 | if (!strcmp(arg, "-a")) { | |
133 | merge_all(); | |
134 | continue; | |
135 | } | |
215a7ad1 | 136 | die("git-merge-index: unknown option %s", arg); |
75118b13 LT |
137 | } |
138 | merge_file(arg); | |
139 | } | |
b32e986c | 140 | if (err && !quiet) |
8c59926f | 141 | die("merge program failed"); |
bbd14cb0 | 142 | return err; |
75118b13 | 143 | } |