THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

755 lines
23KB

  1. #include "cache.h"
  2. #include "commit.h"
  3. #include "refs.h"
  4. #include "object-store.h"
  5. #include "repository.h"
  6. #include "diff.h"
  7. #include "diffcore.h"
  8. #include "xdiff-interface.h"
  9. #include "ll-merge.h"
  10. #include "dir.h"
  11. #include "notes.h"
  12. #include "notes-merge.h"
  13. #include "strbuf.h"
  14. #include "notes-utils.h"
  15. #include "commit-reach.h"
  16. struct notes_merge_pair {
  17. struct object_id obj, base, local, remote;
  18. };
  19. void init_notes_merge_options(struct repository *r,
  20. struct notes_merge_options *o)
  21. {
  22. memset(o, 0, sizeof(struct notes_merge_options));
  23. strbuf_init(&(o->commit_msg), 0);
  24. o->verbosity = NOTES_MERGE_VERBOSITY_DEFAULT;
  25. o->repo = r;
  26. }
  27. static int path_to_oid(const char *path, struct object_id *oid)
  28. {
  29. char hex_oid[GIT_MAX_HEXSZ];
  30. int i = 0;
  31. while (*path && i < the_hash_algo->hexsz) {
  32. if (*path != '/')
  33. hex_oid[i++] = *path;
  34. path++;
  35. }
  36. if (*path || i != the_hash_algo->hexsz)
  37. return -1;
  38. return get_oid_hex(hex_oid, oid);
  39. }
  40. static int verify_notes_filepair(struct diff_filepair *p, struct object_id *oid)
  41. {
  42. switch (p->status) {
  43. case DIFF_STATUS_MODIFIED:
  44. assert(p->one->mode == p->two->mode);
  45. assert(!is_null_oid(&p->one->oid));
  46. assert(!is_null_oid(&p->two->oid));
  47. break;
  48. case DIFF_STATUS_ADDED:
  49. assert(is_null_oid(&p->one->oid));
  50. break;
  51. case DIFF_STATUS_DELETED:
  52. assert(is_null_oid(&p->two->oid));
  53. break;
  54. default:
  55. return -1;
  56. }
  57. assert(!strcmp(p->one->path, p->two->path));
  58. return path_to_oid(p->one->path, oid);
  59. }
  60. static struct notes_merge_pair *find_notes_merge_pair_pos(
  61. struct notes_merge_pair *list, int len, struct object_id *obj,
  62. int insert_new, int *occupied)
  63. {
  64. /*
  65. * Both diff_tree_remote() and diff_tree_local() tend to process
  66. * merge_pairs in ascending order. Therefore, cache last returned
  67. * index, and search sequentially from there until the appropriate
  68. * position is found.
  69. *
  70. * Since inserts only happen from diff_tree_remote() (which mainly
  71. * _appends_), we don't care that inserting into the middle of the
  72. * list is expensive (using memmove()).
  73. */
  74. static int last_index;
  75. int i = last_index < len ? last_index : len - 1;
  76. int prev_cmp = 0, cmp = -1;
  77. while (i >= 0 && i < len) {
  78. cmp = oidcmp(obj, &list[i].obj);
  79. if (!cmp) /* obj belongs @ i */
  80. break;
  81. else if (cmp < 0 && prev_cmp <= 0) /* obj belongs < i */
  82. i--;
  83. else if (cmp < 0) /* obj belongs between i-1 and i */
  84. break;
  85. else if (cmp > 0 && prev_cmp >= 0) /* obj belongs > i */
  86. i++;
  87. else /* if (cmp > 0) */ { /* obj belongs between i and i+1 */
  88. i++;
  89. break;
  90. }
  91. prev_cmp = cmp;
  92. }
  93. if (i < 0)
  94. i = 0;
  95. /* obj belongs at, or immediately preceding, index i (0 <= i <= len) */
  96. if (!cmp)
  97. *occupied = 1;
  98. else {
  99. *occupied = 0;
  100. if (insert_new && i < len) {
  101. MOVE_ARRAY(list + i + 1, list + i, len - i);
  102. memset(list + i, 0, sizeof(struct notes_merge_pair));
  103. }
  104. }
  105. last_index = i;
  106. return list + i;
  107. }
  108. static struct object_id uninitialized = {
  109. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \
  110. "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
  111. };
  112. static struct notes_merge_pair *diff_tree_remote(struct notes_merge_options *o,
  113. const struct object_id *base,
  114. const struct object_id *remote,
  115. int *num_changes)
  116. {
  117. struct diff_options opt;
  118. struct notes_merge_pair *changes;
  119. int i, len = 0;
  120. trace_printf("\tdiff_tree_remote(base = %.7s, remote = %.7s)\n",
  121. oid_to_hex(base), oid_to_hex(remote));
  122. repo_diff_setup(o->repo, &opt);
  123. opt.flags.recursive = 1;
  124. opt.output_format = DIFF_FORMAT_NO_OUTPUT;
  125. diff_setup_done(&opt);
  126. diff_tree_oid(base, remote, "", &opt);
  127. diffcore_std(&opt);
  128. changes = xcalloc(diff_queued_diff.nr, sizeof(struct notes_merge_pair));
  129. for (i = 0; i < diff_queued_diff.nr; i++) {
  130. struct diff_filepair *p = diff_queued_diff.queue[i];
  131. struct notes_merge_pair *mp;
  132. int occupied;
  133. struct object_id obj;
  134. if (verify_notes_filepair(p, &obj)) {
  135. trace_printf("\t\tCannot merge entry '%s' (%c): "
  136. "%.7s -> %.7s. Skipping!\n", p->one->path,
  137. p->status, oid_to_hex(&p->one->oid),
  138. oid_to_hex(&p->two->oid));
  139. continue;
  140. }
  141. mp = find_notes_merge_pair_pos(changes, len, &obj, 1, &occupied);
  142. if (occupied) {
  143. /* We've found an addition/deletion pair */
  144. assert(oideq(&mp->obj, &obj));
  145. if (is_null_oid(&p->one->oid)) { /* addition */
  146. assert(is_null_oid(&mp->remote));
  147. oidcpy(&mp->remote, &p->two->oid);
  148. } else if (is_null_oid(&p->two->oid)) { /* deletion */
  149. assert(is_null_oid(&mp->base));
  150. oidcpy(&mp->base, &p->one->oid);
  151. } else
  152. assert(!"Invalid existing change recorded");
  153. } else {
  154. oidcpy(&mp->obj, &obj);
  155. oidcpy(&mp->base, &p->one->oid);
  156. oidcpy(&mp->local, &uninitialized);
  157. oidcpy(&mp->remote, &p->two->oid);
  158. len++;
  159. }
  160. trace_printf("\t\tStored remote change for %s: %.7s -> %.7s\n",
  161. oid_to_hex(&mp->obj), oid_to_hex(&mp->base),
  162. oid_to_hex(&mp->remote));
  163. }
  164. diff_flush(&opt);
  165. clear_pathspec(&opt.pathspec);
  166. *num_changes = len;
  167. return changes;
  168. }
  169. static void diff_tree_local(struct notes_merge_options *o,
  170. struct notes_merge_pair *changes, int len,
  171. const struct object_id *base,
  172. const struct object_id *local)
  173. {
  174. struct diff_options opt;
  175. int i;
  176. trace_printf("\tdiff_tree_local(len = %i, base = %.7s, local = %.7s)\n",
  177. len, oid_to_hex(base), oid_to_hex(local));
  178. repo_diff_setup(o->repo, &opt);
  179. opt.flags.recursive = 1;
  180. opt.output_format = DIFF_FORMAT_NO_OUTPUT;
  181. diff_setup_done(&opt);
  182. diff_tree_oid(base, local, "", &opt);
  183. diffcore_std(&opt);
  184. for (i = 0; i < diff_queued_diff.nr; i++) {
  185. struct diff_filepair *p = diff_queued_diff.queue[i];
  186. struct notes_merge_pair *mp;
  187. int match;
  188. struct object_id obj;
  189. if (verify_notes_filepair(p, &obj)) {
  190. trace_printf("\t\tCannot merge entry '%s' (%c): "
  191. "%.7s -> %.7s. Skipping!\n", p->one->path,
  192. p->status, oid_to_hex(&p->one->oid),
  193. oid_to_hex(&p->two->oid));
  194. continue;
  195. }
  196. mp = find_notes_merge_pair_pos(changes, len, &obj, 0, &match);
  197. if (!match) {
  198. trace_printf("\t\tIgnoring local-only change for %s: "
  199. "%.7s -> %.7s\n", oid_to_hex(&obj),
  200. oid_to_hex(&p->one->oid),
  201. oid_to_hex(&p->two->oid));
  202. continue;
  203. }
  204. assert(oideq(&mp->obj, &obj));
  205. if (is_null_oid(&p->two->oid)) { /* deletion */
  206. /*
  207. * Either this is a true deletion (1), or it is part
  208. * of an A/D pair (2), or D/A pair (3):
  209. *
  210. * (1) mp->local is uninitialized; set it to null_sha1
  211. * (2) mp->local is not uninitialized; don't touch it
  212. * (3) mp->local is uninitialized; set it to null_sha1
  213. * (will be overwritten by following addition)
  214. */
  215. if (oideq(&mp->local, &uninitialized))
  216. oidclr(&mp->local);
  217. } else if (is_null_oid(&p->one->oid)) { /* addition */
  218. /*
  219. * Either this is a true addition (1), or it is part
  220. * of an A/D pair (2), or D/A pair (3):
  221. *
  222. * (1) mp->local is uninitialized; set to p->two->sha1
  223. * (2) mp->local is uninitialized; set to p->two->sha1
  224. * (3) mp->local is null_sha1; set to p->two->sha1
  225. */
  226. assert(is_null_oid(&mp->local) ||
  227. oideq(&mp->local, &uninitialized));
  228. oidcpy(&mp->local, &p->two->oid);
  229. } else { /* modification */
  230. /*
  231. * This is a true modification. p->one->sha1 shall
  232. * match mp->base, and mp->local shall be uninitialized.
  233. * Set mp->local to p->two->sha1.
  234. */
  235. assert(oideq(&p->one->oid, &mp->base));
  236. assert(oideq(&mp->local, &uninitialized));
  237. oidcpy(&mp->local, &p->two->oid);
  238. }
  239. trace_printf("\t\tStored local change for %s: %.7s -> %.7s\n",
  240. oid_to_hex(&mp->obj), oid_to_hex(&mp->base),
  241. oid_to_hex(&mp->local));
  242. }
  243. diff_flush(&opt);
  244. clear_pathspec(&opt.pathspec);
  245. }
  246. static void check_notes_merge_worktree(struct notes_merge_options *o)
  247. {
  248. if (!o->has_worktree) {
  249. /*
  250. * Must establish NOTES_MERGE_WORKTREE.
  251. * Abort if NOTES_MERGE_WORKTREE already exists
  252. */
  253. if (file_exists(git_path(NOTES_MERGE_WORKTREE)) &&
  254. !is_empty_dir(git_path(NOTES_MERGE_WORKTREE))) {
  255. if (advice_resolve_conflict)
  256. die(_("You have not concluded your previous "
  257. "notes merge (%s exists).\nPlease, use "
  258. "'git notes merge --commit' or 'git notes "
  259. "merge --abort' to commit/abort the "
  260. "previous merge before you start a new "
  261. "notes merge."), git_path("NOTES_MERGE_*"));
  262. else
  263. die(_("You have not concluded your notes merge "
  264. "(%s exists)."), git_path("NOTES_MERGE_*"));
  265. }
  266. if (safe_create_leading_directories_const(git_path(
  267. NOTES_MERGE_WORKTREE "/.test")))
  268. die_errno("unable to create directory %s",
  269. git_path(NOTES_MERGE_WORKTREE));
  270. o->has_worktree = 1;
  271. } else if (!file_exists(git_path(NOTES_MERGE_WORKTREE)))
  272. /* NOTES_MERGE_WORKTREE should already be established */
  273. die("missing '%s'. This should not happen",
  274. git_path(NOTES_MERGE_WORKTREE));
  275. }
  276. static void write_buf_to_worktree(const struct object_id *obj,
  277. const char *buf, unsigned long size)
  278. {
  279. int fd;
  280. char *path = git_pathdup(NOTES_MERGE_WORKTREE "/%s", oid_to_hex(obj));
  281. if (safe_create_leading_directories_const(path))
  282. die_errno("unable to create directory for '%s'", path);
  283. fd = xopen(path, O_WRONLY | O_EXCL | O_CREAT, 0666);
  284. while (size > 0) {
  285. ssize_t ret = write_in_full(fd, buf, size);
  286. if (ret < 0) {
  287. /* Ignore epipe */
  288. if (errno == EPIPE)
  289. break;
  290. die_errno("notes-merge");
  291. }
  292. size -= ret;
  293. buf += ret;
  294. }
  295. close(fd);
  296. free(path);
  297. }
  298. static void write_note_to_worktree(const struct object_id *obj,
  299. const struct object_id *note)
  300. {
  301. enum object_type type;
  302. unsigned long size;
  303. void *buf = read_object_file(note, &type, &size);
  304. if (!buf)
  305. die("cannot read note %s for object %s",
  306. oid_to_hex(note), oid_to_hex(obj));
  307. if (type != OBJ_BLOB)
  308. die("blob expected in note %s for object %s",
  309. oid_to_hex(note), oid_to_hex(obj));
  310. write_buf_to_worktree(obj, buf, size);
  311. free(buf);
  312. }
  313. static int ll_merge_in_worktree(struct notes_merge_options *o,
  314. struct notes_merge_pair *p)
  315. {
  316. mmbuffer_t result_buf;
  317. mmfile_t base, local, remote;
  318. int status;
  319. read_mmblob(&base, &p->base);
  320. read_mmblob(&local, &p->local);
  321. read_mmblob(&remote, &p->remote);
  322. status = ll_merge(&result_buf, oid_to_hex(&p->obj), &base, NULL,
  323. &local, o->local_ref, &remote, o->remote_ref,
  324. o->repo->index, NULL);
  325. free(base.ptr);
  326. free(local.ptr);
  327. free(remote.ptr);
  328. if ((status < 0) || !result_buf.ptr)
  329. die("Failed to execute internal merge");
  330. write_buf_to_worktree(&p->obj, result_buf.ptr, result_buf.size);
  331. free(result_buf.ptr);
  332. return status;
  333. }
  334. static int merge_one_change_manual(struct notes_merge_options *o,
  335. struct notes_merge_pair *p,
  336. struct notes_tree *t)
  337. {
  338. const char *lref = o->local_ref ? o->local_ref : "local version";
  339. const char *rref = o->remote_ref ? o->remote_ref : "remote version";
  340. trace_printf("\t\t\tmerge_one_change_manual(obj = %.7s, base = %.7s, "
  341. "local = %.7s, remote = %.7s)\n",
  342. oid_to_hex(&p->obj), oid_to_hex(&p->base),
  343. oid_to_hex(&p->local), oid_to_hex(&p->remote));
  344. /* add "Conflicts:" section to commit message first time through */
  345. if (!o->has_worktree)
  346. strbuf_addstr(&(o->commit_msg), "\n\nConflicts:\n");
  347. strbuf_addf(&(o->commit_msg), "\t%s\n", oid_to_hex(&p->obj));
  348. if (o->verbosity >= 2)
  349. printf("Auto-merging notes for %s\n", oid_to_hex(&p->obj));
  350. check_notes_merge_worktree(o);
  351. if (is_null_oid(&p->local)) {
  352. /* D/F conflict, checkout p->remote */
  353. assert(!is_null_oid(&p->remote));
  354. if (o->verbosity >= 1)
  355. printf("CONFLICT (delete/modify): Notes for object %s "
  356. "deleted in %s and modified in %s. Version from %s "
  357. "left in tree.\n",
  358. oid_to_hex(&p->obj), lref, rref, rref);
  359. write_note_to_worktree(&p->obj, &p->remote);
  360. } else if (is_null_oid(&p->remote)) {
  361. /* D/F conflict, checkout p->local */
  362. assert(!is_null_oid(&p->local));
  363. if (o->verbosity >= 1)
  364. printf("CONFLICT (delete/modify): Notes for object %s "
  365. "deleted in %s and modified in %s. Version from %s "
  366. "left in tree.\n",
  367. oid_to_hex(&p->obj), rref, lref, lref);
  368. write_note_to_worktree(&p->obj, &p->local);
  369. } else {
  370. /* "regular" conflict, checkout result of ll_merge() */
  371. const char *reason = "content";
  372. if (is_null_oid(&p->base))
  373. reason = "add/add";
  374. assert(!is_null_oid(&p->local));
  375. assert(!is_null_oid(&p->remote));
  376. if (o->verbosity >= 1)
  377. printf("CONFLICT (%s): Merge conflict in notes for "
  378. "object %s\n", reason,
  379. oid_to_hex(&p->obj));
  380. ll_merge_in_worktree(o, p);
  381. }
  382. trace_printf("\t\t\tremoving from partial merge result\n");
  383. remove_note(t, p->obj.hash);
  384. return 1;
  385. }
  386. static int merge_one_change(struct notes_merge_options *o,
  387. struct notes_merge_pair *p, struct notes_tree *t)
  388. {
  389. /*
  390. * Return 0 if change is successfully resolved (stored in notes_tree).
  391. * Return 1 is change results in a conflict (NOT stored in notes_tree,
  392. * but instead written to NOTES_MERGE_WORKTREE with conflict markers).
  393. */
  394. switch (o->strategy) {
  395. case NOTES_MERGE_RESOLVE_MANUAL:
  396. return merge_one_change_manual(o, p, t);
  397. case NOTES_MERGE_RESOLVE_OURS:
  398. if (o->verbosity >= 2)
  399. printf("Using local notes for %s\n",
  400. oid_to_hex(&p->obj));
  401. /* nothing to do */
  402. return 0;
  403. case NOTES_MERGE_RESOLVE_THEIRS:
  404. if (o->verbosity >= 2)
  405. printf("Using remote notes for %s\n",
  406. oid_to_hex(&p->obj));
  407. if (add_note(t, &p->obj, &p->remote, combine_notes_overwrite))
  408. BUG("combine_notes_overwrite failed");
  409. return 0;
  410. case NOTES_MERGE_RESOLVE_UNION:
  411. if (o->verbosity >= 2)
  412. printf("Concatenating local and remote notes for %s\n",
  413. oid_to_hex(&p->obj));
  414. if (add_note(t, &p->obj, &p->remote, combine_notes_concatenate))
  415. die("failed to concatenate notes "
  416. "(combine_notes_concatenate)");
  417. return 0;
  418. case NOTES_MERGE_RESOLVE_CAT_SORT_UNIQ:
  419. if (o->verbosity >= 2)
  420. printf("Concatenating unique lines in local and remote "
  421. "notes for %s\n", oid_to_hex(&p->obj));
  422. if (add_note(t, &p->obj, &p->remote, combine_notes_cat_sort_uniq))
  423. die("failed to concatenate notes "
  424. "(combine_notes_cat_sort_uniq)");
  425. return 0;
  426. }
  427. die("Unknown strategy (%i).", o->strategy);
  428. }
  429. static int merge_changes(struct notes_merge_options *o,
  430. struct notes_merge_pair *changes, int *num_changes,
  431. struct notes_tree *t)
  432. {
  433. int i, conflicts = 0;
  434. trace_printf("\tmerge_changes(num_changes = %i)\n", *num_changes);
  435. for (i = 0; i < *num_changes; i++) {
  436. struct notes_merge_pair *p = changes + i;
  437. trace_printf("\t\t%.7s: %.7s -> %.7s/%.7s\n",
  438. oid_to_hex(&p->obj), oid_to_hex(&p->base),
  439. oid_to_hex(&p->local),
  440. oid_to_hex(&p->remote));
  441. if (oideq(&p->base, &p->remote)) {
  442. /* no remote change; nothing to do */
  443. trace_printf("\t\t\tskipping (no remote change)\n");
  444. } else if (oideq(&p->local, &p->remote)) {
  445. /* same change in local and remote; nothing to do */
  446. trace_printf("\t\t\tskipping (local == remote)\n");
  447. } else if (oideq(&p->local, &uninitialized) ||
  448. oideq(&p->local, &p->base)) {
  449. /* no local change; adopt remote change */
  450. trace_printf("\t\t\tno local change, adopted remote\n");
  451. if (add_note(t, &p->obj, &p->remote,
  452. combine_notes_overwrite))
  453. BUG("combine_notes_overwrite failed");
  454. } else {
  455. /* need file-level merge between local and remote */
  456. trace_printf("\t\t\tneed content-level merge\n");
  457. conflicts += merge_one_change(o, p, t);
  458. }
  459. }
  460. return conflicts;
  461. }
  462. static int merge_from_diffs(struct notes_merge_options *o,
  463. const struct object_id *base,
  464. const struct object_id *local,
  465. const struct object_id *remote,
  466. struct notes_tree *t)
  467. {
  468. struct notes_merge_pair *changes;
  469. int num_changes, conflicts;
  470. trace_printf("\tmerge_from_diffs(base = %.7s, local = %.7s, "
  471. "remote = %.7s)\n", oid_to_hex(base), oid_to_hex(local),
  472. oid_to_hex(remote));
  473. changes = diff_tree_remote(o, base, remote, &num_changes);
  474. diff_tree_local(o, changes, num_changes, base, local);
  475. conflicts = merge_changes(o, changes, &num_changes, t);
  476. free(changes);
  477. if (o->verbosity >= 4)
  478. printf(t->dirty ?
  479. "Merge result: %i unmerged notes and a dirty notes tree\n" :
  480. "Merge result: %i unmerged notes and a clean notes tree\n",
  481. conflicts);
  482. return conflicts ? -1 : 1;
  483. }
  484. int notes_merge(struct notes_merge_options *o,
  485. struct notes_tree *local_tree,
  486. struct object_id *result_oid)
  487. {
  488. struct object_id local_oid, remote_oid;
  489. struct commit *local, *remote;
  490. struct commit_list *bases = NULL;
  491. const struct object_id *base_oid, *base_tree_oid;
  492. int result = 0;
  493. assert(o->local_ref && o->remote_ref);
  494. assert(!strcmp(o->local_ref, local_tree->ref));
  495. oidclr(result_oid);
  496. trace_printf("notes_merge(o->local_ref = %s, o->remote_ref = %s)\n",
  497. o->local_ref, o->remote_ref);
  498. /* Dereference o->local_ref into local_sha1 */
  499. if (read_ref_full(o->local_ref, 0, &local_oid, NULL))
  500. die("Failed to resolve local notes ref '%s'", o->local_ref);
  501. else if (!check_refname_format(o->local_ref, 0) &&
  502. is_null_oid(&local_oid))
  503. local = NULL; /* local_oid == null_oid indicates unborn ref */
  504. else if (!(local = lookup_commit_reference(o->repo, &local_oid)))
  505. die("Could not parse local commit %s (%s)",
  506. oid_to_hex(&local_oid), o->local_ref);
  507. trace_printf("\tlocal commit: %.7s\n", oid_to_hex(&local_oid));
  508. /* Dereference o->remote_ref into remote_oid */
  509. if (get_oid(o->remote_ref, &remote_oid)) {
  510. /*
  511. * Failed to get remote_oid. If o->remote_ref looks like an
  512. * unborn ref, perform the merge using an empty notes tree.
  513. */
  514. if (!check_refname_format(o->remote_ref, 0)) {
  515. oidclr(&remote_oid);
  516. remote = NULL;
  517. } else {
  518. die("Failed to resolve remote notes ref '%s'",
  519. o->remote_ref);
  520. }
  521. } else if (!(remote = lookup_commit_reference(o->repo, &remote_oid))) {
  522. die("Could not parse remote commit %s (%s)",
  523. oid_to_hex(&remote_oid), o->remote_ref);
  524. }
  525. trace_printf("\tremote commit: %.7s\n", oid_to_hex(&remote_oid));
  526. if (!local && !remote)
  527. die("Cannot merge empty notes ref (%s) into empty notes ref "
  528. "(%s)", o->remote_ref, o->local_ref);
  529. if (!local) {
  530. /* result == remote commit */
  531. oidcpy(result_oid, &remote_oid);
  532. goto found_result;
  533. }
  534. if (!remote) {
  535. /* result == local commit */
  536. oidcpy(result_oid, &local_oid);
  537. goto found_result;
  538. }
  539. assert(local && remote);
  540. /* Find merge bases */
  541. bases = get_merge_bases(local, remote);
  542. if (!bases) {
  543. base_oid = &null_oid;
  544. base_tree_oid = the_hash_algo->empty_tree;
  545. if (o->verbosity >= 4)
  546. printf("No merge base found; doing history-less merge\n");
  547. } else if (!bases->next) {
  548. base_oid = &bases->item->object.oid;
  549. base_tree_oid = get_commit_tree_oid(bases->item);
  550. if (o->verbosity >= 4)
  551. printf("One merge base found (%.7s)\n",
  552. oid_to_hex(base_oid));
  553. } else {
  554. /* TODO: How to handle multiple merge-bases? */
  555. base_oid = &bases->item->object.oid;
  556. base_tree_oid = get_commit_tree_oid(bases->item);
  557. if (o->verbosity >= 3)
  558. printf("Multiple merge bases found. Using the first "
  559. "(%.7s)\n", oid_to_hex(base_oid));
  560. }
  561. if (o->verbosity >= 4)
  562. printf("Merging remote commit %.7s into local commit %.7s with "
  563. "merge-base %.7s\n", oid_to_hex(&remote->object.oid),
  564. oid_to_hex(&local->object.oid),
  565. oid_to_hex(base_oid));
  566. if (oideq(&remote->object.oid, base_oid)) {
  567. /* Already merged; result == local commit */
  568. if (o->verbosity >= 2)
  569. printf("Already up to date!\n");
  570. oidcpy(result_oid, &local->object.oid);
  571. goto found_result;
  572. }
  573. if (oideq(&local->object.oid, base_oid)) {
  574. /* Fast-forward; result == remote commit */
  575. if (o->verbosity >= 2)
  576. printf("Fast-forward\n");
  577. oidcpy(result_oid, &remote->object.oid);
  578. goto found_result;
  579. }
  580. result = merge_from_diffs(o, base_tree_oid,
  581. get_commit_tree_oid(local),
  582. get_commit_tree_oid(remote), local_tree);
  583. if (result != 0) { /* non-trivial merge (with or without conflicts) */
  584. /* Commit (partial) result */
  585. struct commit_list *parents = NULL;
  586. commit_list_insert(remote, &parents); /* LIFO order */
  587. commit_list_insert(local, &parents);
  588. create_notes_commit(o->repo, local_tree, parents, o->commit_msg.buf,
  589. o->commit_msg.len, result_oid);
  590. }
  591. found_result:
  592. free_commit_list(bases);
  593. strbuf_release(&(o->commit_msg));
  594. trace_printf("notes_merge(): result = %i, result_oid = %.7s\n",
  595. result, oid_to_hex(result_oid));
  596. return result;
  597. }
  598. int notes_merge_commit(struct notes_merge_options *o,
  599. struct notes_tree *partial_tree,
  600. struct commit *partial_commit,
  601. struct object_id *result_oid)
  602. {
  603. /*
  604. * Iterate through files in .git/NOTES_MERGE_WORKTREE and add all
  605. * found notes to 'partial_tree'. Write the updated notes tree to
  606. * the DB, and commit the resulting tree object while reusing the
  607. * commit message and parents from 'partial_commit'.
  608. * Finally store the new commit object OID into 'result_oid'.
  609. */
  610. DIR *dir;
  611. struct dirent *e;
  612. struct strbuf path = STRBUF_INIT;
  613. const char *buffer = get_commit_buffer(partial_commit, NULL);
  614. const char *msg = strstr(buffer, "\n\n");
  615. int baselen;
  616. git_path_buf(&path, NOTES_MERGE_WORKTREE);
  617. if (o->verbosity >= 3)
  618. printf("Committing notes in notes merge worktree at %s\n",
  619. path.buf);
  620. if (!msg || msg[2] == '\0')
  621. die("partial notes commit has empty message");
  622. msg += 2;
  623. dir = opendir(path.buf);
  624. if (!dir)
  625. die_errno("could not open %s", path.buf);
  626. strbuf_addch(&path, '/');
  627. baselen = path.len;
  628. while ((e = readdir(dir)) != NULL) {
  629. struct stat st;
  630. struct object_id obj_oid, blob_oid;
  631. if (is_dot_or_dotdot(e->d_name))
  632. continue;
  633. if (get_oid_hex(e->d_name, &obj_oid)) {
  634. if (o->verbosity >= 3)
  635. printf("Skipping non-SHA1 entry '%s%s'\n",
  636. path.buf, e->d_name);
  637. continue;
  638. }
  639. strbuf_addstr(&path, e->d_name);
  640. /* write file as blob, and add to partial_tree */
  641. if (stat(path.buf, &st))
  642. die_errno("Failed to stat '%s'", path.buf);
  643. if (index_path(o->repo->index, &blob_oid, path.buf, &st, HASH_WRITE_OBJECT))
  644. die("Failed to write blob object from '%s'", path.buf);
  645. if (add_note(partial_tree, &obj_oid, &blob_oid, NULL))
  646. die("Failed to add resolved note '%s' to notes tree",
  647. path.buf);
  648. if (o->verbosity >= 4)
  649. printf("Added resolved note for object %s: %s\n",
  650. oid_to_hex(&obj_oid), oid_to_hex(&blob_oid));
  651. strbuf_setlen(&path, baselen);
  652. }
  653. create_notes_commit(o->repo, partial_tree, partial_commit->parents, msg,
  654. strlen(msg), result_oid);
  655. unuse_commit_buffer(partial_commit, buffer);
  656. if (o->verbosity >= 4)
  657. printf("Finalized notes merge commit: %s\n",
  658. oid_to_hex(result_oid));
  659. strbuf_release(&path);
  660. closedir(dir);
  661. return 0;
  662. }
  663. int notes_merge_abort(struct notes_merge_options *o)
  664. {
  665. /*
  666. * Remove all files within .git/NOTES_MERGE_WORKTREE. We do not remove
  667. * the .git/NOTES_MERGE_WORKTREE directory itself, since it might be
  668. * the current working directory of the user.
  669. */
  670. struct strbuf buf = STRBUF_INIT;
  671. int ret;
  672. git_path_buf(&buf, NOTES_MERGE_WORKTREE);
  673. if (o->verbosity >= 3)
  674. printf("Removing notes merge worktree at %s/*\n", buf.buf);
  675. ret = remove_dir_recursively(&buf, REMOVE_DIR_KEEP_TOPLEVEL);
  676. strbuf_release(&buf);
  677. return ret;
  678. }