merge-index.c 2.3 KB

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