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