use sha1_to_hex_r() instead of strcpy
[git/git.git] / builtin / merge-index.c
CommitLineData
c2e86add 1#include "builtin.h"
b49809c9 2#include "run-command.h"
75118b13 3
96f1e58f 4static const char *pgm;
bbd14cb0 5static int one_shot, quiet;
8c59926f 6static int err;
75118b13 7
75118b13
LT
8static int merge_entry(int pos, const char *path)
9{
10 int found;
0077138c 11 const char *arguments[] = { pgm, "", "", "", path, "", "", "", NULL };
d59f765a 12 char hexbuf[4][GIT_SHA1_HEXSZ + 1];
0077138c 13 char ownbuf[4][60];
a6080a0a 14
75118b13 15 if (pos >= active_nr)
7e44c935 16 die("git merge-index: %s not in the cache", path);
75118b13
LT
17 found = 0;
18 do {
9c5e6c80 19 const struct cache_entry *ce = active_cache[pos];
75118b13
LT
20 int stage = ce_stage(ce);
21
22 if (strcmp(ce->name, path))
23 break;
24 found++;
d59f765a 25 sha1_to_hex_r(hexbuf[stage], ce->sha1);
5096d490 26 xsnprintf(ownbuf[stage], sizeof(ownbuf[stage]), "%o", ce->ce_mode);
e3b4be7f 27 arguments[stage] = hexbuf[stage];
e2b6a9d0 28 arguments[stage + 4] = ownbuf[stage];
75118b13
LT
29 } while (++pos < active_nr);
30 if (!found)
7e44c935 31 die("git merge-index: %s not in the cache", path);
0077138c
JS
32
33 if (run_command_v_opt(arguments, 0)) {
34 if (one_shot)
35 err++;
36 else {
37 if (!quiet)
38 die("merge program failed");
39 exit(1);
40 }
41 }
75118b13
LT
42 return found;
43}
44
fa2364ec 45static void merge_one_path(const char *path)
75118b13
LT
46{
47 int pos = cache_name_pos(path, strlen(path));
48
49 /*
50 * If it already exists in the cache as stage0, it's
51 * already merged and there is nothing to do.
52 */
53 if (pos < 0)
54 merge_entry(-pos-1, path);
55}
56
57static void merge_all(void)
58{
59 int i;
60 for (i = 0; i < active_nr; i++) {
9c5e6c80 61 const struct cache_entry *ce = active_cache[i];
75118b13
LT
62 if (!ce_stage(ce))
63 continue;
64 i += merge_entry(i, ce->name)-1;
65 }
66}
67
0ecace72 68int cmd_merge_index(int argc, const char **argv, const char *prefix)
75118b13
LT
69{
70 int i, force_file = 0;
71
f0b7367c
JH
72 /* Without this we cannot rely on waitpid() to tell
73 * what happened to our children.
74 */
75 signal(SIGCHLD, SIG_DFL);
76
75118b13 77 if (argc < 3)
9c9b4f2f 78 usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])");
75118b13
LT
79
80 read_cache();
81
2a459251 82 i = 1;
bbd14cb0 83 if (!strcmp(argv[i], "-o")) {
2a459251
PB
84 one_shot = 1;
85 i++;
86 }
bbd14cb0
PB
87 if (!strcmp(argv[i], "-q")) {
88 quiet = 1;
89 i++;
90 }
2a459251
PB
91 pgm = argv[i++];
92 for (; i < argc; i++) {
0ecace72 93 const char *arg = argv[i];
75118b13
LT
94 if (!force_file && *arg == '-') {
95 if (!strcmp(arg, "--")) {
96 force_file = 1;
97 continue;
98 }
99 if (!strcmp(arg, "-a")) {
100 merge_all();
101 continue;
102 }
7e44c935 103 die("git merge-index: unknown option %s", arg);
75118b13 104 }
fa2364ec 105 merge_one_path(arg);
75118b13 106 }
b32e986c 107 if (err && !quiet)
8c59926f 108 die("merge program failed");
bbd14cb0 109 return err;
75118b13 110}