]>
Commit | Line | Data |
---|---|---|
75118b13 LT |
1 | #include <sys/types.h> |
2 | #include <sys/wait.h> | |
3 | ||
4 | #include "cache.h" | |
5 | ||
6 | static const char *pgm = NULL; | |
e2b6a9d0 | 7 | static const char *arguments[8]; |
75118b13 LT |
8 | |
9 | static void run_program(void) | |
10 | { | |
11 | int pid = fork(), status; | |
12 | ||
13 | if (pid < 0) | |
14 | die("unable to fork"); | |
15 | if (!pid) { | |
16 | execlp(pgm, arguments[0], | |
17 | arguments[1], | |
18 | arguments[2], | |
19 | arguments[3], | |
20 | arguments[4], | |
e2b6a9d0 JB |
21 | arguments[5], |
22 | arguments[6], | |
23 | arguments[7], | |
75118b13 LT |
24 | NULL); |
25 | die("unable to execute '%s'", pgm); | |
26 | } | |
27 | if (waitpid(pid, &status, 0) < 0 || !WIFEXITED(status) || WEXITSTATUS(status)) | |
28 | die("merge program failed"); | |
29 | } | |
30 | ||
75118b13 LT |
31 | static int merge_entry(int pos, const char *path) |
32 | { | |
33 | int found; | |
34 | ||
35 | if (pos >= active_nr) | |
36 | die("merge-cache: %s not in the cache", path); | |
37 | arguments[0] = pgm; | |
38 | arguments[1] = ""; | |
39 | arguments[2] = ""; | |
40 | arguments[3] = ""; | |
41 | arguments[4] = path; | |
e2b6a9d0 JB |
42 | arguments[5] = ""; |
43 | arguments[6] = ""; | |
44 | arguments[7] = ""; | |
75118b13 LT |
45 | found = 0; |
46 | do { | |
e3b4be7f | 47 | static char hexbuf[4][60]; |
e2b6a9d0 | 48 | static char ownbuf[4][60]; |
75118b13 LT |
49 | struct cache_entry *ce = active_cache[pos]; |
50 | int stage = ce_stage(ce); | |
51 | ||
52 | if (strcmp(ce->name, path)) | |
53 | break; | |
54 | found++; | |
e3b4be7f | 55 | strcpy(hexbuf[stage], sha1_to_hex(ce->sha1)); |
e2b6a9d0 | 56 | sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode) & (~S_IFMT)); |
e3b4be7f | 57 | arguments[stage] = hexbuf[stage]; |
e2b6a9d0 | 58 | arguments[stage + 4] = ownbuf[stage]; |
75118b13 LT |
59 | } while (++pos < active_nr); |
60 | if (!found) | |
61 | die("merge-cache: %s not in the cache", path); | |
62 | run_program(); | |
63 | return found; | |
64 | } | |
65 | ||
66 | static void merge_file(const char *path) | |
67 | { | |
68 | int pos = cache_name_pos(path, strlen(path)); | |
69 | ||
70 | /* | |
71 | * If it already exists in the cache as stage0, it's | |
72 | * already merged and there is nothing to do. | |
73 | */ | |
74 | if (pos < 0) | |
75 | merge_entry(-pos-1, path); | |
76 | } | |
77 | ||
78 | static void merge_all(void) | |
79 | { | |
80 | int i; | |
81 | for (i = 0; i < active_nr; i++) { | |
82 | struct cache_entry *ce = active_cache[i]; | |
83 | if (!ce_stage(ce)) | |
84 | continue; | |
85 | i += merge_entry(i, ce->name)-1; | |
86 | } | |
87 | } | |
88 | ||
89 | int main(int argc, char **argv) | |
90 | { | |
91 | int i, force_file = 0; | |
92 | ||
93 | if (argc < 3) | |
94 | usage("merge-cache <merge-program> (-a | <filename>*)"); | |
95 | ||
96 | read_cache(); | |
97 | ||
98 | pgm = argv[1]; | |
99 | for (i = 2; i < argc; i++) { | |
100 | char *arg = argv[i]; | |
101 | if (!force_file && *arg == '-') { | |
102 | if (!strcmp(arg, "--")) { | |
103 | force_file = 1; | |
104 | continue; | |
105 | } | |
106 | if (!strcmp(arg, "-a")) { | |
107 | merge_all(); | |
108 | continue; | |
109 | } | |
110 | die("merge-cache: unknown option %s", arg); | |
111 | } | |
112 | merge_file(arg); | |
113 | } | |
114 | return 0; | |
115 | } |