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