Merge branch 'rj/cygwin-has-dev-tty'
[git/gitster.git] / builtin / merge-index.c
blob0fabe3f6bb2092e9e9eec8ee81f3784ecd1c7da5
1 #include "builtin.h"
2 #include "hex.h"
3 #include "read-cache-ll.h"
4 #include "repository.h"
5 #include "run-command.h"
6 #include "sparse-index.h"
8 static const char *pgm;
9 static int one_shot, quiet;
10 static int err;
12 static int merge_entry(int pos, const char *path)
14 int found;
15 const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
16 char hexbuf[4][GIT_MAX_HEXSZ + 1];
17 char ownbuf[4][60];
18 struct child_process cmd = CHILD_PROCESS_INIT;
20 if (pos >= the_repository->index->cache_nr)
21 die("git merge-index: %s not in the cache", path);
22 found = 0;
23 do {
24 const struct cache_entry *ce = the_repository->index->cache[pos];
25 int stage = ce_stage(ce);
27 if (strcmp(ce->name, path))
28 break;
29 found++;
30 oid_to_hex_r(hexbuf[stage], &ce->oid);
31 xsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), "%o", ce->ce_mode);
32 arguments[stage] = hexbuf[stage];
33 arguments[stage + 4] = ownbuf[stage];
34 } while (++pos < the_repository->index->cache_nr);
35 if (!found)
36 die("git merge-index: %s not in the cache", path);
38 strvec_pushv(&cmd.args, arguments);
39 if (run_command(&cmd)) {
40 if (one_shot)
41 err++;
42 else {
43 if (!quiet)
44 die("merge program failed");
45 exit(1);
48 return found;
51 static void merge_one_path(const char *path)
53 int pos = index_name_pos(the_repository->index, path, strlen(path));
56 * If it already exists in the cache as stage0, it's
57 * already merged and there is nothing to do.
59 if (pos < 0)
60 merge_entry(-pos-1, path);
63 static void merge_all(void)
65 int i;
66 /* TODO: audit for interaction with sparse-index. */
67 ensure_full_index(the_repository->index);
68 for (i = 0; i < the_repository->index->cache_nr; i++) {
69 const struct cache_entry *ce = the_repository->index->cache[i];
70 if (!ce_stage(ce))
71 continue;
72 i += merge_entry(i, ce->name)-1;
76 int cmd_merge_index(int argc, const char **argv, const char *prefix UNUSED)
78 int i, force_file = 0;
80 /* Without this we cannot rely on waitpid() to tell
81 * what happened to our children.
83 signal(SIGCHLD, SIG_DFL);
85 if (argc < 3)
86 usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])");
88 repo_read_index(the_repository);
90 /* TODO: audit for interaction with sparse-index. */
91 ensure_full_index(the_repository->index);
93 i = 1;
94 if (!strcmp(argv[i], "-o")) {
95 one_shot = 1;
96 i++;
98 if (!strcmp(argv[i], "-q")) {
99 quiet = 1;
100 i++;
102 pgm = argv[i++];
103 for (; i < argc; i++) {
104 const char *arg = argv[i];
105 if (!force_file && *arg == '-') {
106 if (!strcmp(arg, "--")) {
107 force_file = 1;
108 continue;
110 if (!strcmp(arg, "-a")) {
111 merge_all();
112 continue;
114 die("git merge-index: unknown option %s", arg);
116 merge_one_path(arg);
118 if (err && !quiet)
119 die("merge program failed");
120 return err;