merge-tree.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. #define USE_THE_INDEX_COMPATIBILITY_MACROS
  2. #include "builtin.h"
  3. #include "tree-walk.h"
  4. #include "xdiff-interface.h"
  5. #include "object-store.h"
  6. #include "repository.h"
  7. #include "blob.h"
  8. #include "exec-cmd.h"
  9. #include "merge-blobs.h"
  10. static const char merge_tree_usage[] = "git merge-tree <base-tree> <branch1> <branch2>";
  11. struct merge_list {
  12. struct merge_list *next;
  13. struct merge_list *link; /* other stages for this object */
  14. unsigned int stage : 2;
  15. unsigned int mode;
  16. const char *path;
  17. struct blob *blob;
  18. };
  19. static struct merge_list *merge_result, **merge_result_end = &merge_result;
  20. static void add_merge_entry(struct merge_list *entry)
  21. {
  22. *merge_result_end = entry;
  23. merge_result_end = &entry->next;
  24. }
  25. static void merge_trees(struct tree_desc t[3], const char *base);
  26. static const char *explanation(struct merge_list *entry)
  27. {
  28. switch (entry->stage) {
  29. case 0:
  30. return "merged";
  31. case 3:
  32. return "added in remote";
  33. case 2:
  34. if (entry->link)
  35. return "added in both";
  36. return "added in local";
  37. }
  38. /* Existed in base */
  39. entry = entry->link;
  40. if (!entry)
  41. return "removed in both";
  42. if (entry->link)
  43. return "changed in both";
  44. if (entry->stage == 3)
  45. return "removed in local";
  46. return "removed in remote";
  47. }
  48. static void *result(struct merge_list *entry, unsigned long *size)
  49. {
  50. enum object_type type;
  51. struct blob *base, *our, *their;
  52. const char *path = entry->path;
  53. if (!entry->stage)
  54. return read_object_file(&entry->blob->object.oid, &type, size);
  55. base = NULL;
  56. if (entry->stage == 1) {
  57. base = entry->blob;
  58. entry = entry->link;
  59. }
  60. our = NULL;
  61. if (entry && entry->stage == 2) {
  62. our = entry->blob;
  63. entry = entry->link;
  64. }
  65. their = NULL;
  66. if (entry)
  67. their = entry->blob;
  68. return merge_blobs(the_repository->index, path,
  69. base, our, their, size);
  70. }
  71. static void *origin(struct merge_list *entry, unsigned long *size)
  72. {
  73. enum object_type type;
  74. while (entry) {
  75. if (entry->stage == 2)
  76. return read_object_file(&entry->blob->object.oid,
  77. &type, size);
  78. entry = entry->link;
  79. }
  80. return NULL;
  81. }
  82. static int show_outf(void *priv_, mmbuffer_t *mb, int nbuf)
  83. {
  84. int i;
  85. for (i = 0; i < nbuf; i++)
  86. printf("%.*s", (int) mb[i].size, mb[i].ptr);
  87. return 0;
  88. }
  89. static void show_diff(struct merge_list *entry)
  90. {
  91. unsigned long size;
  92. mmfile_t src, dst;
  93. xpparam_t xpp;
  94. xdemitconf_t xecfg;
  95. xdemitcb_t ecb;
  96. xpp.flags = 0;
  97. memset(&xecfg, 0, sizeof(xecfg));
  98. xecfg.ctxlen = 3;
  99. ecb.out_hunk = NULL;
  100. ecb.out_line = show_outf;
  101. ecb.priv = NULL;
  102. src.ptr = origin(entry, &size);
  103. if (!src.ptr)
  104. size = 0;
  105. src.size = size;
  106. dst.ptr = result(entry, &size);
  107. if (!dst.ptr)
  108. size = 0;
  109. dst.size = size;
  110. if (xdi_diff(&src, &dst, &xpp, &xecfg, &ecb))
  111. die("unable to generate diff");
  112. free(src.ptr);
  113. free(dst.ptr);
  114. }
  115. static void show_result_list(struct merge_list *entry)
  116. {
  117. printf("%s\n", explanation(entry));
  118. do {
  119. struct merge_list *link = entry->link;
  120. static const char *desc[4] = { "result", "base", "our", "their" };
  121. printf(" %-6s %o %s %s\n", desc[entry->stage], entry->mode, oid_to_hex(&entry->blob->object.oid), entry->path);
  122. entry = link;
  123. } while (entry);
  124. }
  125. static void show_result(void)
  126. {
  127. struct merge_list *walk;
  128. walk = merge_result;
  129. while (walk) {
  130. show_result_list(walk);
  131. show_diff(walk);
  132. walk = walk->next;
  133. }
  134. }
  135. /* An empty entry never compares same, not even to another empty entry */
  136. static int same_entry(struct name_entry *a, struct name_entry *b)
  137. {
  138. return !is_null_oid(&a->oid) &&
  139. !is_null_oid(&b->oid) &&
  140. oideq(&a->oid, &b->oid) &&
  141. a->mode == b->mode;
  142. }
  143. static int both_empty(struct name_entry *a, struct name_entry *b)
  144. {
  145. return is_null_oid(&a->oid) && is_null_oid(&b->oid);
  146. }
  147. static struct merge_list *create_entry(unsigned stage, unsigned mode, const struct object_id *oid, const char *path)
  148. {
  149. struct merge_list *res = xcalloc(1, sizeof(*res));
  150. res->stage = stage;
  151. res->path = path;
  152. res->mode = mode;
  153. res->blob = lookup_blob(the_repository, oid);
  154. return res;
  155. }
  156. static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
  157. {
  158. struct strbuf buf = STRBUF_INIT;
  159. strbuf_make_traverse_path(&buf, info, n->path, n->pathlen);
  160. return strbuf_detach(&buf, NULL);
  161. }
  162. static void resolve(const struct traverse_info *info, struct name_entry *ours, struct name_entry *result)
  163. {
  164. struct merge_list *orig, *final;
  165. const char *path;
  166. /* If it's already ours, don't bother showing it */
  167. if (!ours)
  168. return;
  169. path = traverse_path(info, result);
  170. orig = create_entry(2, ours->mode, &ours->oid, path);
  171. final = create_entry(0, result->mode, &result->oid, path);
  172. final->link = orig;
  173. add_merge_entry(final);
  174. }
  175. static void unresolved_directory(const struct traverse_info *info,
  176. struct name_entry n[3])
  177. {
  178. struct repository *r = the_repository;
  179. char *newbase;
  180. struct name_entry *p;
  181. struct tree_desc t[3];
  182. void *buf0, *buf1, *buf2;
  183. for (p = n; p < n + 3; p++) {
  184. if (p->mode && S_ISDIR(p->mode))
  185. break;
  186. }
  187. if (n + 3 <= p)
  188. return; /* there is no tree here */
  189. newbase = traverse_path(info, p);
  190. #define ENTRY_OID(e) (((e)->mode && S_ISDIR((e)->mode)) ? &(e)->oid : NULL)
  191. buf0 = fill_tree_descriptor(r, t + 0, ENTRY_OID(n + 0));
  192. buf1 = fill_tree_descriptor(r, t + 1, ENTRY_OID(n + 1));
  193. buf2 = fill_tree_descriptor(r, t + 2, ENTRY_OID(n + 2));
  194. #undef ENTRY_OID
  195. merge_trees(t, newbase);
  196. free(buf0);
  197. free(buf1);
  198. free(buf2);
  199. free(newbase);
  200. }
  201. static struct merge_list *link_entry(unsigned stage, const struct traverse_info *info, struct name_entry *n, struct merge_list *entry)
  202. {
  203. const char *path;
  204. struct merge_list *link;
  205. if (!n->mode)
  206. return entry;
  207. if (entry)
  208. path = entry->path;
  209. else
  210. path = traverse_path(info, n);
  211. link = create_entry(stage, n->mode, &n->oid, path);
  212. link->link = entry;
  213. return link;
  214. }
  215. static void unresolved(const struct traverse_info *info, struct name_entry n[3])
  216. {
  217. struct merge_list *entry = NULL;
  218. int i;
  219. unsigned dirmask = 0, mask = 0;
  220. for (i = 0; i < 3; i++) {
  221. mask |= (1 << i);
  222. /*
  223. * Treat missing entries as directories so that we return
  224. * after unresolved_directory has handled this.
  225. */
  226. if (!n[i].mode || S_ISDIR(n[i].mode))
  227. dirmask |= (1 << i);
  228. }
  229. unresolved_directory(info, n);
  230. if (dirmask == mask)
  231. return;
  232. if (n[2].mode && !S_ISDIR(n[2].mode))
  233. entry = link_entry(3, info, n + 2, entry);
  234. if (n[1].mode && !S_ISDIR(n[1].mode))
  235. entry = link_entry(2, info, n + 1, entry);
  236. if (n[0].mode && !S_ISDIR(n[0].mode))
  237. entry = link_entry(1, info, n + 0, entry);
  238. add_merge_entry(entry);
  239. }
  240. /*
  241. * Merge two trees together (t[1] and t[2]), using a common base (t[0])
  242. * as the origin.
  243. *
  244. * This walks the (sorted) trees in lock-step, checking every possible
  245. * name. Note that directories automatically sort differently from other
  246. * files (see "base_name_compare"), so you'll never see file/directory
  247. * conflicts, because they won't ever compare the same.
  248. *
  249. * IOW, if a directory changes to a filename, it will automatically be
  250. * seen as the directory going away, and the filename being created.
  251. *
  252. * Think of this as a three-way diff.
  253. *
  254. * The output will be either:
  255. * - successful merge
  256. * "0 mode sha1 filename"
  257. * NOTE NOTE NOTE! FIXME! We really really need to walk the index
  258. * in parallel with this too!
  259. *
  260. * - conflict:
  261. * "1 mode sha1 filename"
  262. * "2 mode sha1 filename"
  263. * "3 mode sha1 filename"
  264. * where not all of the 1/2/3 lines may exist, of course.
  265. *
  266. * The successful merge rules are the same as for the three-way merge
  267. * in git-read-tree.
  268. */
  269. static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *info)
  270. {
  271. /* Same in both? */
  272. if (same_entry(entry+1, entry+2) || both_empty(entry+1, entry+2)) {
  273. /* Modified, added or removed identically */
  274. resolve(info, NULL, entry+1);
  275. return mask;
  276. }
  277. if (same_entry(entry+0, entry+1)) {
  278. if (!is_null_oid(&entry[2].oid) && !S_ISDIR(entry[2].mode)) {
  279. /* We did not touch, they modified -- take theirs */
  280. resolve(info, entry+1, entry+2);
  281. return mask;
  282. }
  283. /*
  284. * If we did not touch a directory but they made it
  285. * into a file, we fall through and unresolved()
  286. * recurses down. Likewise for the opposite case.
  287. */
  288. }
  289. if (same_entry(entry+0, entry+2) || both_empty(entry+0, entry+2)) {
  290. /* We added, modified or removed, they did not touch -- take ours */
  291. resolve(info, NULL, entry+1);
  292. return mask;
  293. }
  294. unresolved(info, entry);
  295. return mask;
  296. }
  297. static void merge_trees(struct tree_desc t[3], const char *base)
  298. {
  299. struct traverse_info info;
  300. setup_traverse_info(&info, base);
  301. info.fn = threeway_callback;
  302. traverse_trees(&the_index, 3, t, &info);
  303. }
  304. static void *get_tree_descriptor(struct repository *r,
  305. struct tree_desc *desc,
  306. const char *rev)
  307. {
  308. struct object_id oid;
  309. void *buf;
  310. if (repo_get_oid(r, rev, &oid))
  311. die("unknown rev %s", rev);
  312. buf = fill_tree_descriptor(r, desc, &oid);
  313. if (!buf)
  314. die("%s is not a tree", rev);
  315. return buf;
  316. }
  317. int cmd_merge_tree(int argc, const char **argv, const char *prefix)
  318. {
  319. struct repository *r = the_repository;
  320. struct tree_desc t[3];
  321. void *buf1, *buf2, *buf3;
  322. if (argc != 4)
  323. usage(merge_tree_usage);
  324. buf1 = get_tree_descriptor(r, t+0, argv[1]);
  325. buf2 = get_tree_descriptor(r, t+1, argv[2]);
  326. buf3 = get_tree_descriptor(r, t+2, argv[3]);
  327. merge_trees(t, "");
  328. free(buf1);
  329. free(buf2);
  330. free(buf3);
  331. show_result();
  332. return 0;
  333. }