Merge branch 'ak/restore-both-incompatible-with-conflicts'
[git/debian.git] / builtin / merge-index.c
blobc875f5d37ee63f489f03a3f0f8007998fca69ca0
1 #define USE_THE_INDEX_VARIABLE
2 #include "builtin.h"
3 #include "hex.h"
4 #include "run-command.h"
6 static const char *pgm;
7 static int one_shot, quiet;
8 static int err;
10 static int merge_entry(int pos, const char *path)
12 int found;
13 const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
14 char hexbuf[4][GIT_MAX_HEXSZ + 1];
15 char ownbuf[4][60];
16 struct child_process cmd = CHILD_PROCESS_INIT;
18 if (pos >= the_index.cache_nr)
19 die("git merge-index: %s not in the cache", path);
20 found = 0;
21 do {
22 const struct cache_entry *ce = the_index.cache[pos];
23 int stage = ce_stage(ce);
25 if (strcmp(ce->name, path))
26 break;
27 found++;
28 oid_to_hex_r(hexbuf[stage], &ce->oid);
29 xsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), "%o", ce->ce_mode);
30 arguments[stage] = hexbuf[stage];
31 arguments[stage + 4] = ownbuf[stage];
32 } while (++pos < the_index.cache_nr);
33 if (!found)
34 die("git merge-index: %s not in the cache", path);
36 strvec_pushv(&cmd.args, arguments);
37 if (run_command(&cmd)) {
38 if (one_shot)
39 err++;
40 else {
41 if (!quiet)
42 die("merge program failed");
43 exit(1);
46 return found;
49 static void merge_one_path(const char *path)
51 int pos = index_name_pos(&the_index, path, strlen(path));
54 * If it already exists in the cache as stage0, it's
55 * already merged and there is nothing to do.
57 if (pos < 0)
58 merge_entry(-pos-1, path);
61 static void merge_all(void)
63 int i;
64 /* TODO: audit for interaction with sparse-index. */
65 ensure_full_index(&the_index);
66 for (i = 0; i < the_index.cache_nr; i++) {
67 const struct cache_entry *ce = the_index.cache[i];
68 if (!ce_stage(ce))
69 continue;
70 i += merge_entry(i, ce->name)-1;
74 int cmd_merge_index(int argc, const char **argv, const char *prefix)
76 int i, force_file = 0;
78 /* Without this we cannot rely on waitpid() to tell
79 * what happened to our children.
81 signal(SIGCHLD, SIG_DFL);
83 if (argc < 3)
84 usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])");
86 repo_read_index(the_repository);
88 /* TODO: audit for interaction with sparse-index. */
89 ensure_full_index(&the_index);
91 i = 1;
92 if (!strcmp(argv[i], "-o")) {
93 one_shot = 1;
94 i++;
96 if (!strcmp(argv[i], "-q")) {
97 quiet = 1;
98 i++;
100 pgm = argv[i++];
101 for (; i < argc; i++) {
102 const char *arg = argv[i];
103 if (!force_file && *arg == '-') {
104 if (!strcmp(arg, "--")) {
105 force_file = 1;
106 continue;
108 if (!strcmp(arg, "-a")) {
109 merge_all();
110 continue;
112 die("git merge-index: unknown option %s", arg);
114 merge_one_path(arg);
116 if (err && !quiet)
117 die("merge program failed");
118 return err;