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