Git 2.34.8
[git.git] / builtin / merge-index.c
blobc0383fe9df9a3eb2e34f8c5869f996ebc81fce2e
1 #define USE_THE_INDEX_COMPATIBILITY_MACROS
2 #include "builtin.h"
3 #include "run-command.h"
5 static const char *pgm;
6 static int one_shot, quiet;
7 static int err;
9 static int merge_entry(int pos, const char *path)
11 int found;
12 const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
13 char hexbuf[4][GIT_MAX_HEXSZ + 1];
14 char ownbuf[4][60];
16 if (pos >= active_nr)
17 die("git merge-index: %s not in the cache", path);
18 found = 0;
19 do {
20 const struct cache_entry *ce = active_cache[pos];
21 int stage = ce_stage(ce);
23 if (strcmp(ce->name, path))
24 break;
25 found++;
26 oid_to_hex_r(hexbuf[stage], &ce->oid);
27 xsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), "%o", ce->ce_mode);
28 arguments[stage] = hexbuf[stage];
29 arguments[stage + 4] = ownbuf[stage];
30 } while (++pos < active_nr);
31 if (!found)
32 die("git merge-index: %s not in the cache", path);
34 if (run_command_v_opt(arguments, 0)) {
35 if (one_shot)
36 err++;
37 else {
38 if (!quiet)
39 die("merge program failed");
40 exit(1);
43 return found;
46 static void merge_one_path(const char *path)
48 int pos = cache_name_pos(path, strlen(path));
51 * If it already exists in the cache as stage0, it's
52 * already merged and there is nothing to do.
54 if (pos < 0)
55 merge_entry(-pos-1, path);
58 static void merge_all(void)
60 int i;
61 /* TODO: audit for interaction with sparse-index. */
62 ensure_full_index(&the_index);
63 for (i = 0; i < active_nr; i++) {
64 const struct cache_entry *ce = active_cache[i];
65 if (!ce_stage(ce))
66 continue;
67 i += merge_entry(i, ce->name)-1;
71 int cmd_merge_index(int argc, const char **argv, const char *prefix)
73 int i, force_file = 0;
75 /* Without this we cannot rely on waitpid() to tell
76 * what happened to our children.
78 signal(SIGCHLD, SIG_DFL);
80 if (argc < 3)
81 usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])");
83 read_cache();
85 /* TODO: audit for interaction with sparse-index. */
86 ensure_full_index(&the_index);
88 i = 1;
89 if (!strcmp(argv[i], "-o")) {
90 one_shot = 1;
91 i++;
93 if (!strcmp(argv[i], "-q")) {
94 quiet = 1;
95 i++;
97 pgm = argv[i++];
98 for (; i < argc; i++) {
99 const char *arg = argv[i];
100 if (!force_file && *arg == '-') {
101 if (!strcmp(arg, "--")) {
102 force_file = 1;
103 continue;
105 if (!strcmp(arg, "-a")) {
106 merge_all();
107 continue;
109 die("git merge-index: unknown option %s", arg);
111 merge_one_path(arg);
113 if (err && !quiet)
114 die("merge program failed");
115 return err;