1#include "cache.h"
2#include "run-command.h"
34
static const char *pgm;
5static const char *arguments[8];
6static int one_shot, quiet;
7static int err;
89
static void run_program(void)
10{
11struct child_process child;
12memset(&child, 0, sizeof(child));
13child.argv = arguments;
14if (run_command(&child)) {
15if (one_shot) {
16err++;
17} else {
18if (!quiet)
19die("merge program failed");
20exit(1);
21}
22}
23}
2425
static int merge_entry(int pos, const char *path)
26{
27int found;
2829
if (pos >= active_nr)
30die("git-merge-index: %s not in the cache", path);
31arguments[0] = pgm;
32arguments[1] = "";
33arguments[2] = "";
34arguments[3] = "";
35arguments[4] = path;
36arguments[5] = "";
37arguments[6] = "";
38arguments[7] = "";
39found = 0;
40do {
41static char hexbuf[4][60];
42static char ownbuf[4][60];
43struct cache_entry *ce = active_cache[pos];
44int stage = ce_stage(ce);
4546
if (strcmp(ce->name, path))
47break;
48found++;
49strcpy(hexbuf[stage], sha1_to_hex(ce->sha1));
50sprintf(ownbuf[stage], "%o", ntohl(ce->ce_mode));
51arguments[stage] = hexbuf[stage];
52arguments[stage + 4] = ownbuf[stage];
53} while (++pos < active_nr);
54if (!found)
55die("git-merge-index: %s not in the cache", path);
56run_program();
57return found;
58}
5960
static void merge_file(const char *path)
61{
62int pos = cache_name_pos(path, strlen(path));
6364
/*
65* If it already exists in the cache as stage0, it's
66* already merged and there is nothing to do.
67*/
68if (pos < 0)
69merge_entry(-pos-1, path);
70}
7172
static void merge_all(void)
73{
74int i;
75for (i = 0; i < active_nr; i++) {
76struct cache_entry *ce = active_cache[i];
77if (!ce_stage(ce))
78continue;
79i += merge_entry(i, ce->name)-1;
80}
81}
8283
int main(int argc, char **argv)
84{
85int i, force_file = 0;
8687
/* Without this we cannot rely on waitpid() to tell
88* what happened to our children.
89*/
90signal(SIGCHLD, SIG_DFL);
9192
if (argc < 3)
93usage("git-merge-index [-o] [-q] <merge-program> (-a | <filename>*)");
9495
setup_git_directory();
96read_cache();
9798
i = 1;
99if (!strcmp(argv[i], "-o")) {
100one_shot = 1;
101i++;
102}
103if (!strcmp(argv[i], "-q")) {
104quiet = 1;
105i++;
106}
107pgm = argv[i++];
108for (; i < argc; i++) {
109char *arg = argv[i];
110if (!force_file && *arg == '-') {
111if (!strcmp(arg, "--")) {
112force_file = 1;
113continue;
114}
115if (!strcmp(arg, "-a")) {
116merge_all();
117continue;
118}
119die("git-merge-index: unknown option %s", arg);
120}
121merge_file(arg);
122}
123if (err && !quiet)
124die("merge program failed");
125return err;
126}