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