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