PageRenderTime 63ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/monotone-1.0/src/cmd_merging.cc

#
C++ | 1562 lines | 1107 code | 241 blank | 214 comment | 119 complexity | 59075190d850f16c950e821669982f67 MD5 | raw file
Possible License(s): GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. // Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
  2. // 2008, 2010 Stephen Leake <stephen_leake@stephe-leake.org>
  3. //
  4. // This program is made available under the GNU GPL version 2.0 or
  5. // greater. See the accompanying file COPYING for details.
  6. //
  7. // This program is distributed WITHOUT ANY WARRANTY; without even the
  8. // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  9. // PURPOSE.
  10. #include "base.hh"
  11. #include <cstring>
  12. #include <iostream>
  13. #include <iomanip>
  14. #include "basic_io.hh"
  15. #include "cmd.hh"
  16. #include "diff_output.hh"
  17. #include "merge_content.hh"
  18. #include "restrictions.hh"
  19. #include "revision.hh"
  20. #include "merge_roster.hh"
  21. #include "transforms.hh"
  22. #include "update.hh"
  23. #include "work.hh"
  24. #include "safe_map.hh"
  25. #include "app_state.hh"
  26. #include "maybe_workspace_updater.hh"
  27. #include "project.hh"
  28. #include "simplestring_xform.hh"
  29. #include "keys.hh"
  30. #include "key_store.hh"
  31. #include "database.hh"
  32. #include "vocab_cast.hh"
  33. using std::cout;
  34. using std::make_pair;
  35. using std::map;
  36. using std::set;
  37. using std::string;
  38. using std::vector;
  39. using std::strlen;
  40. using boost::shared_ptr;
  41. static void
  42. add_dormant_attrs(const_node_t parent, node_t child)
  43. {
  44. for (attr_map_t::const_iterator i = parent->attrs.begin();
  45. i != parent->attrs.end(); ++i)
  46. {
  47. // if the child does not have the associated attr add a dormant one
  48. if (child->attrs.find(i->first) == child->attrs.end())
  49. safe_insert(child->attrs,
  50. make_pair(i->first, make_pair(false, attr_value())));
  51. }
  52. }
  53. static void
  54. three_way_merge(revision_id const & ancestor_rid, roster_t const & ancestor_roster,
  55. revision_id const & left_rid, roster_t const & left_roster,
  56. revision_id const & right_rid, roster_t const & right_roster,
  57. roster_merge_result & result,
  58. marking_map & left_markings,
  59. marking_map & right_markings)
  60. {
  61. MM(ancestor_roster);
  62. MM(left_roster);
  63. MM(right_roster);
  64. MM(ancestor_rid);
  65. MM(left_rid);
  66. MM(right_rid);
  67. // for this to work correctly attrs that exist in the ancestor *must*
  68. // exist in both children, since attrs are never deleted they are only
  69. // marked as dormant. however, since this may be any arbitrary arrangement
  70. // of three revisions it is possible that attrs do exist in the parent and
  71. // not in the children. in this case the attrs must be added to the
  72. // children as dormant so that roster_merge works correctly.
  73. roster_t left_with_attrs(left_roster);
  74. roster_t right_with_attrs(right_roster);
  75. MM(left_with_attrs);
  76. MM(right_with_attrs);
  77. node_map const & nodes = ancestor_roster.all_nodes();
  78. for (node_map::const_iterator i = nodes.begin(); i != nodes.end(); ++i)
  79. {
  80. if (left_with_attrs.has_node(i->first))
  81. add_dormant_attrs(i->second, left_with_attrs.get_node_for_update(i->first));
  82. if (right_with_attrs.has_node(i->first))
  83. add_dormant_attrs(i->second, right_with_attrs.get_node_for_update(i->first));
  84. }
  85. // Mark up the ANCESTOR
  86. marking_map ancestor_markings; MM(ancestor_markings);
  87. mark_roster_with_no_parents(ancestor_rid, ancestor_roster, ancestor_markings);
  88. // Mark up the LEFT roster
  89. left_markings.clear();
  90. MM(left_markings);
  91. mark_roster_with_one_parent(ancestor_roster, ancestor_markings,
  92. left_rid, left_with_attrs, left_markings);
  93. // Mark up the RIGHT roster
  94. right_markings.clear();
  95. MM(right_markings);
  96. mark_roster_with_one_parent(ancestor_roster, ancestor_markings,
  97. right_rid, right_with_attrs, right_markings);
  98. // Make the synthetic graph, by creating uncommon ancestor sets
  99. std::set<revision_id> left_uncommon_ancestors, right_uncommon_ancestors;
  100. safe_insert(left_uncommon_ancestors, left_rid);
  101. safe_insert(right_uncommon_ancestors, right_rid);
  102. P(F("[left] %s") % left_rid);
  103. P(F("[right] %s") % right_rid);
  104. // And do the merge
  105. roster_merge(left_with_attrs, left_markings, left_uncommon_ancestors,
  106. right_with_attrs, right_markings, right_uncommon_ancestors,
  107. result);
  108. }
  109. static bool
  110. pick_branch_for_update(options & opts, database & db,
  111. project_t & project, revision_id chosen_rid)
  112. {
  113. bool switched_branch = false;
  114. // figure out which branches the target is in
  115. vector<cert> certs;
  116. db.get_revision_certs(chosen_rid, branch_cert_name, certs);
  117. db.erase_bogus_certs(project, certs);
  118. set<branch_name> branches;
  119. for (vector<cert>::const_iterator i = certs.begin();
  120. i != certs.end(); i++)
  121. branches.insert(typecast_vocab<branch_name>(i->value));
  122. if (!opts.ignore_suspend_certs)
  123. {
  124. vector<cert> suspend_certs;
  125. db.get_revision_certs(chosen_rid, suspend_cert_name, suspend_certs);
  126. for (vector<cert>::const_iterator i = suspend_certs.begin();
  127. i != suspend_certs.end(); i++)
  128. {
  129. branch_name susp_branch = typecast_vocab<branch_name>(i->value);
  130. set<branch_name>::iterator pos = branches.find(susp_branch);
  131. if (pos != branches.end())
  132. {
  133. branches.erase(pos);
  134. }
  135. }
  136. }
  137. if (branches.find(opts.branch) != branches.end())
  138. {
  139. L(FL("using existing branch %s") % opts.branch());
  140. }
  141. else
  142. {
  143. P(F("target revision is not in current branch"));
  144. if (branches.size() > 1)
  145. {
  146. // multiple non-matching branchnames
  147. string branch_list;
  148. for (set<branch_name>::const_iterator i = branches.begin();
  149. i != branches.end(); i++)
  150. branch_list += "\n " + (*i)();
  151. E(false, origin::user,
  152. F("target revision is in multiple branches:%s\n\n"
  153. "Try again with explicit '--branch'") % branch_list);
  154. }
  155. else if (branches.size() == 1)
  156. {
  157. // one non-matching, inform and update
  158. opts.branch = *(branches.begin());
  159. switched_branch = true;
  160. }
  161. else
  162. {
  163. W(F("target revision not in any branch.\n"
  164. "Next commit will use branch '%s'")
  165. % opts.branch);
  166. }
  167. }
  168. return switched_branch;
  169. }
  170. // also used from maybe_workspace_updater.cc
  171. void
  172. update(app_state & app,
  173. args_vector const & args)
  174. {
  175. database db(app);
  176. workspace work(app);
  177. project_t project(db);
  178. // Figure out where we are
  179. parent_map parents;
  180. work.get_parent_rosters(db, parents);
  181. E(parents.size() == 1, origin::user,
  182. F("this command can only be used in a single-parent workspace"));
  183. revision_id old_rid = parent_id(parents.begin());
  184. E(!null_id(old_rid), origin::user,
  185. F("this workspace is a new project; cannot update"));
  186. // Figure out where we're going
  187. E(!app.opts.branch().empty(), origin::user,
  188. F("cannot determine branch for update"));
  189. revision_id chosen_rid;
  190. if (app.opts.revision.empty())
  191. {
  192. P(F("updating along branch '%s'") % app.opts.branch);
  193. set<revision_id> candidates;
  194. pick_update_candidates(app.lua, project, candidates, old_rid,
  195. app.opts.branch,
  196. app.opts.ignore_suspend_certs);
  197. E(!candidates.empty(), origin::user,
  198. F("your request matches no descendents of the current revision.\n"
  199. "In fact, it doesn't even match the current revision.\n"
  200. "Maybe you want something like '--revision=h:%s'")
  201. % app.opts.branch);
  202. if (candidates.size() != 1)
  203. {
  204. P(F("multiple update candidates:"));
  205. for (set<revision_id>::const_iterator i = candidates.begin();
  206. i != candidates.end(); ++i)
  207. P(i18n_format(" %s")
  208. % describe_revision(app.opts, app.lua, project, *i));
  209. P(F("choose one with '%s update -r<id>'") % prog_name);
  210. E(false, origin::user,
  211. F("multiple update candidates remain after selection"));
  212. }
  213. chosen_rid = *(candidates.begin());
  214. }
  215. else
  216. {
  217. complete(app.opts, app.lua, project, app.opts.revision[0](), chosen_rid);
  218. }
  219. I(!null_id(chosen_rid));
  220. // do this notification before checking to see if we can bail out early,
  221. // because when you are at one of several heads, and you hit update, you
  222. // want to know that merging would let you update further.
  223. notify_if_multiple_heads(project,
  224. app.opts.branch, app.opts.ignore_suspend_certs);
  225. if (old_rid == chosen_rid)
  226. {
  227. P(F("already up to date at %s") % old_rid);
  228. // do still switch the workspace branch, in case they have used
  229. // update to switch branches.
  230. work.set_options(app.opts, app.lua, true);
  231. return;
  232. }
  233. P(F("selected update target %s") % chosen_rid);
  234. // Fiddle around with branches, in an attempt to guess what the user
  235. // wants.
  236. bool switched_branch = pick_branch_for_update(app.opts, db, project, chosen_rid);
  237. if (switched_branch)
  238. P(F("switching to branch '%s'") % app.opts.branch());
  239. // Okay, we have a target, we have a branch, let's do this merge!
  240. // We have:
  241. //
  242. // old --> working
  243. // | |
  244. // V V
  245. // chosen --> merged
  246. //
  247. // - old is the revision specified in _MTN/revision
  248. // - working is based on old and includes the workspace's changes
  249. // - chosen is the revision we're updating to and will end up in _MTN/revision
  250. // - merged is the merge of working and chosen, that will become the new
  251. // workspace
  252. //
  253. // we apply the working to merged cset to the workspace
  254. // and write the cset from chosen to merged changeset in _MTN/work
  255. temp_node_id_source nis;
  256. // Get the OLD and WORKING rosters
  257. roster_t_cp old_roster
  258. = parent_cached_roster(parents.begin()).first;
  259. MM(*old_roster);
  260. shared_ptr<roster_t> working_roster = shared_ptr<roster_t>(new roster_t());
  261. MM(*working_roster);
  262. work.get_current_roster_shape(db, nis, *working_roster);
  263. work.update_current_roster_from_filesystem(*working_roster);
  264. revision_t working_rev;
  265. revision_id working_rid;
  266. make_revision_for_workspace(parents, *working_roster, working_rev);
  267. calculate_ident(working_rev, working_rid);
  268. // Get the CHOSEN roster
  269. roster_t chosen_roster; MM(chosen_roster);
  270. db.get_roster(chosen_rid, chosen_roster);
  271. // And finally do the merge
  272. roster_merge_result result;
  273. marking_map left_markings, right_markings;
  274. three_way_merge(old_rid, *old_roster,
  275. working_rid, *working_roster,
  276. chosen_rid, chosen_roster,
  277. result, left_markings, right_markings);
  278. roster_t & merged_roster = result.roster;
  279. map<file_id, file_path> paths;
  280. get_content_paths(*working_roster, paths);
  281. content_merge_workspace_adaptor wca(db, old_rid, old_roster,
  282. left_markings, right_markings, paths);
  283. wca.cache_roster(working_rid, working_roster);
  284. resolve_merge_conflicts(app.lua, app.opts, *working_roster, chosen_roster,
  285. result, wca, false);
  286. // Make sure it worked...
  287. I(result.is_clean());
  288. merged_roster.check_sane(true);
  289. // Now finally modify the workspace
  290. cset update;
  291. make_cset(*working_roster, merged_roster, update);
  292. work.perform_content_update(*working_roster, merged_roster, update, wca, true,
  293. app.opts.move_conflicting_paths);
  294. revision_t remaining;
  295. make_revision_for_workspace(chosen_rid, chosen_roster,
  296. merged_roster, remaining);
  297. // small race condition here... FIXME: what is it?
  298. work.put_update_id(old_rid);
  299. work.put_work_rev(remaining);
  300. work.maybe_update_inodeprints(db);
  301. work.set_options(app.opts, app.lua, true);
  302. if (switched_branch)
  303. P(F("switched branch; next commit will use branch '%s'") % app.opts.branch());
  304. P(F("updated to base revision %s") % chosen_rid);
  305. }
  306. CMD(update, "update", "", CMD_REF(workspace), "",
  307. N_("Updates the workspace"),
  308. N_("This command modifies your workspace to be based off of a "
  309. "different revision, preserving uncommitted changes as it does so. "
  310. "If a revision is given, update the workspace to that revision. "
  311. "If not, update the workspace to the head of the branch."),
  312. options::opts::branch | options::opts::revision |
  313. options::opts::move_conflicting_paths)
  314. {
  315. if (!args.empty())
  316. throw usage(execid);
  317. if (app.opts.revision.size() > 1)
  318. throw usage(execid);
  319. update(app, args);
  320. }
  321. CMD_AUTOMATE(update, "",
  322. N_("Updates the workspace"),
  323. "",
  324. options::opts::branch | options::opts::revision |
  325. options::opts::move_conflicting_paths)
  326. {
  327. E(args.empty(), origin::user,
  328. F("wrong argument count"));
  329. E(app.opts.revision.size() <= 1, origin::user,
  330. F("at most one revision selector may be specified"));
  331. update(app, args);
  332. }
  333. // Subroutine of CMD(merge) and CMD(explicit_merge). Merge LEFT with RIGHT,
  334. // placing results onto BRANCH. Note that interactive_merge_and_store may
  335. // bomb out, and therefore so may this.
  336. static void
  337. merge_two(options & opts, lua_hooks & lua, project_t & project,
  338. key_store & keys,
  339. revision_id const & left, revision_id const & right,
  340. branch_name const & branch, string const & caller,
  341. std::ostream & output, bool automate)
  342. {
  343. // The following mess constructs a neatly formatted log message that looks
  344. // like this:
  345. // CALLER of 'LEFT'
  346. // and 'RIGHT'
  347. // to branch 'BRANCH'
  348. // where the last line is left out if we're merging onto the current branch.
  349. // We use a stringstream because boost::format does not support %-*s.
  350. using std::ostringstream;
  351. using std::setw;
  352. using std::max;
  353. ostringstream log;
  354. utf8 log_message("");
  355. bool log_message_given;
  356. size_t fieldwidth = max(caller.size() + strlen(" of '"), strlen("and '"));
  357. if (branch != opts.branch)
  358. fieldwidth = max(fieldwidth, strlen("to branch '"));
  359. log << setw(fieldwidth - strlen(" of '")) << caller << " of '" << left
  360. << "'\n" << setw(fieldwidth) << "and '" << right
  361. << "'\n";
  362. if (branch != opts.branch)
  363. log << setw(fieldwidth) << "to branch '" << branch << "'\n";
  364. process_commit_message_args(opts, log_message_given, log_message,
  365. utf8(log.str(), origin::internal));
  366. // Now it's time for the real work.
  367. if (automate)
  368. {
  369. output << left << " " << right << " ";
  370. }
  371. else
  372. {
  373. P(F("[left] %s") % left);
  374. P(F("[right] %s") % right);
  375. }
  376. revision_id merged;
  377. transaction_guard guard(project.db);
  378. interactive_merge_and_store(lua, project.db, opts, left, right, merged);
  379. project.put_standard_certs_from_options(opts, lua, keys, merged, branch, log_message);
  380. guard.commit();
  381. if (automate)
  382. output << merged << "\n";
  383. else
  384. P(F("[merged] %s") % merged);
  385. }
  386. typedef std::pair<revision_id, revision_id> revpair;
  387. typedef set<revision_id>::const_iterator rid_set_iter;
  388. // Subroutine of 'merge' and 'automate show_conflicts'; find first pair of
  389. // heads to merge.
  390. static revpair
  391. find_heads_to_merge(database & db, set<revision_id> const heads)
  392. {
  393. I(heads.size() >= 2);
  394. if (heads.size() == 2)
  395. {
  396. rid_set_iter i = heads.begin();
  397. revision_id left = *i++;
  398. revision_id right = *i++;
  399. return revpair(left, right);
  400. };
  401. map<revision_id, revpair> heads_for_ancestor;
  402. set<revision_id> ancestors;
  403. // For every pair of heads, determine their merge ancestor, and
  404. // remember the ancestor->head mapping.
  405. for (rid_set_iter i = heads.begin(); i != heads.end(); ++i)
  406. for (rid_set_iter j = i; j != heads.end(); ++j)
  407. {
  408. // It is not possible to initialize j to i+1 (set iterators
  409. // expose neither operator+ nor a nondestructive next() method)
  410. if (j == i)
  411. continue;
  412. revision_id ancestor;
  413. find_common_ancestor_for_merge(db, *i, *j, ancestor);
  414. // More than one pair might have the same ancestor (e.g. if we
  415. // have three heads all with the same parent); as this table
  416. // will be recalculated on every pass, we just take the first
  417. // one we find.
  418. if (ancestors.insert(ancestor).second)
  419. safe_insert(heads_for_ancestor, std::make_pair(ancestor, revpair(*i, *j)));
  420. }
  421. // Erasing ancestors from ANCESTORS will now produce a set of merge
  422. // ancestors each of which is not itself an ancestor of any other
  423. // merge ancestor.
  424. erase_ancestors(db, ancestors);
  425. I(!ancestors.empty());
  426. // Take the first ancestor from the above set.
  427. return heads_for_ancestor[*ancestors.begin()];
  428. }
  429. // should merge support --message, --message-file? It seems somewhat weird,
  430. // since a single 'merge' command may perform arbitrarily many actual merges.
  431. // (Possibility: append the --message/--message-file text to the synthetic
  432. // log message constructed in merge_two().)
  433. CMD(merge, "merge", "", CMD_REF(tree), "",
  434. N_("Merges unmerged heads of a branch"),
  435. "",
  436. options::opts::branch | options::opts::date | options::opts::author |
  437. options::opts::messages | options::opts::resolve_conflicts_opts |
  438. options::opts::auto_update)
  439. {
  440. database db(app);
  441. key_store keys(app);
  442. project_t project(db);
  443. maybe_workspace_updater updater(app, project);
  444. if (!args.empty())
  445. throw usage(execid);
  446. E(!app.opts.branch().empty(), origin::user,
  447. F("please specify a branch, with '--branch=BRANCH'"));
  448. set<revision_id> heads;
  449. project.get_branch_heads(app.opts.branch, heads,
  450. app.opts.ignore_suspend_certs);
  451. E(!heads.empty(), origin::user,
  452. F("branch '%s' is empty") % app.opts.branch);
  453. if (heads.size() == 1)
  454. {
  455. P(F("branch '%s' is already merged") % app.opts.branch);
  456. return;
  457. }
  458. P(FP("%d head on branch '%s'", "%d heads on branch '%s'", heads.size())
  459. % heads.size() % app.opts.branch);
  460. // avoid failure after lots of work
  461. cache_user_key(app.opts, project, keys, app.lua);
  462. size_t pass = 1, todo = heads.size() - 1;
  463. if (app.opts.resolve_conflicts)
  464. {
  465. // conflicts and resolutions only apply to first merge, so only do that one.
  466. todo = 1;
  467. }
  468. // If there are more than two heads to be merged, on each iteration we
  469. // merge a pair whose least common ancestor is not an ancestor of any
  470. // other pair's least common ancestor. For example, if the history graph
  471. // looks like this:
  472. //
  473. // X
  474. // / \. (periods to prevent multi-line
  475. // Y C comment warnings)
  476. // / \.
  477. // A B
  478. //
  479. // A and B will be merged first, and then the result will be merged with C.
  480. while (pass <= todo)
  481. {
  482. P(F("merge %d / %d:") % pass % todo);
  483. P(F("calculating best pair of heads to merge next"));
  484. revpair p = find_heads_to_merge(db, heads);
  485. merge_two(app.opts, app.lua, project, keys,
  486. p.first, p.second, app.opts.branch, string("merge"),
  487. std::cout, false);
  488. project.get_branch_heads(app.opts.branch, heads,
  489. app.opts.ignore_suspend_certs);
  490. pass++;
  491. }
  492. if (heads.size() > 1)
  493. P(F("note: branch '%s' still has %d heads; run merge again") % app.opts.branch % heads.size());
  494. updater.maybe_do_update();
  495. }
  496. // This is a special merge operator, but very useful for people
  497. // maintaining "slightly disparate but related" trees. It does a one-way
  498. // merge; less powerful than putting things in the same branch and also
  499. // more flexible.
  500. //
  501. // 1. Check to see if src and dst branches are merged, if not abort, if so
  502. // call heads N1 and N2 respectively.
  503. //
  504. // 2. (FIXME: not yet present) Run the hook propagate ("src-branch",
  505. // "dst-branch", N1, N2) which gives the user a chance to massage N1 into
  506. // a state which is likely to "merge nicely" with N2, eg. edit pathnames,
  507. // omit optional files of no interest.
  508. //
  509. // 3. Do a normal 2 or 3-way merge on N1 and N2, depending on the
  510. // existence of common ancestors.
  511. //
  512. // 4. Save the results as the delta (N2,M), the ancestry edges (N1,M)
  513. // and (N2,M), and the cert (N2,dst).
  514. //
  515. // There are also special cases we have to check for where no merge is
  516. // actually necessary, because there hasn't been any divergence since the
  517. // last time propagate was run.
  518. //
  519. // If dir is not the empty string, rename the root of N1 to have the name
  520. // 'dir' in the merged tree. (ie, it has name "basename(dir)", and its
  521. // parent node is "N2.get_node(dirname(dir))")
  522. void perform_merge_into_dir(app_state & app,
  523. commands::command_id const & execid,
  524. args_vector const & args)
  525. {
  526. database db(app);
  527. key_store keys(app);
  528. project_t project(db);
  529. set<revision_id> src_heads, dst_heads;
  530. if (args.size() != 3)
  531. throw usage(execid);
  532. maybe_workspace_updater updater(app, project);
  533. project.get_branch_heads(typecast_vocab<branch_name>(idx(args, 0)), src_heads,
  534. app.opts.ignore_suspend_certs);
  535. project.get_branch_heads(typecast_vocab<branch_name>(idx(args, 1)), dst_heads,
  536. app.opts.ignore_suspend_certs);
  537. E(src_heads.size() != 0, origin::user,
  538. F("branch '%s' is empty") % idx(args, 0)());
  539. E(src_heads.size() == 1, origin::user,
  540. F("branch '%s' is not merged") % idx(args, 0)());
  541. E(dst_heads.size() != 0, origin::user,
  542. F("branch '%s' is empty") % idx(args, 1)());
  543. E(dst_heads.size() == 1, origin::user,
  544. F("branch '%s' is not merged") % idx(args, 1)());
  545. set<revision_id>::const_iterator src_i = src_heads.begin();
  546. set<revision_id>::const_iterator dst_i = dst_heads.begin();
  547. if (*src_i == *dst_i || is_ancestor(db, *src_i, *dst_i))
  548. {
  549. P(F("branch '%s' is up-to-date with respect to branch '%s'")
  550. % idx(args, 1)() % idx(args, 0)());
  551. P(F("no action taken"));
  552. return;
  553. }
  554. cache_user_key(app.opts, project, keys, app.lua);
  555. P(F("propagating %s -> %s") % idx(args,0) % idx(args,1));
  556. P(F("[left] %s") % *src_i);
  557. P(F("[right] %s") % *dst_i);
  558. // check for special cases
  559. if (is_ancestor(db, *dst_i, *src_i))
  560. {
  561. P(F("no merge necessary; putting %s in branch '%s'")
  562. % *src_i % idx(args, 1)());
  563. transaction_guard guard(db);
  564. project.put_revision_in_branch(keys, *src_i,
  565. typecast_vocab<branch_name>(idx(args, 1)));
  566. guard.commit();
  567. }
  568. else
  569. {
  570. revision_id merged;
  571. transaction_guard guard(db);
  572. {
  573. revision_id const & left_rid(*src_i), & right_rid(*dst_i);
  574. roster_t left_roster, right_roster;
  575. MM(left_roster);
  576. MM(right_roster);
  577. marking_map left_marking_map, right_marking_map;
  578. set<revision_id>
  579. left_uncommon_ancestors,
  580. right_uncommon_ancestors;
  581. db.get_roster(left_rid, left_roster, left_marking_map);
  582. db.get_roster(right_rid, right_roster, right_marking_map);
  583. db.get_uncommon_ancestors(left_rid, right_rid,
  584. left_uncommon_ancestors,
  585. right_uncommon_ancestors);
  586. if (!idx(args,2)().empty())
  587. {
  588. dir_t moved_root = left_roster.root();
  589. file_path pth = file_path_external(idx(args, 2));
  590. file_path dir;
  591. path_component base;
  592. MM(dir);
  593. pth.dirname_basename(dir, base);
  594. E(right_roster.has_node(dir), origin::user,
  595. F("Path '%s' not found in destination tree.") % pth);
  596. const_node_t parent = right_roster.get_node(dir);
  597. moved_root->parent = parent->self;
  598. moved_root->name = base;
  599. marking_t i = left_marking_map.get_marking_for_update(moved_root->self);
  600. i->parent_name.clear();
  601. i->parent_name.insert(left_rid);
  602. }
  603. roster_merge_result result;
  604. roster_merge(left_roster,
  605. left_marking_map,
  606. left_uncommon_ancestors,
  607. right_roster,
  608. right_marking_map,
  609. right_uncommon_ancestors,
  610. result);
  611. content_merge_database_adaptor
  612. dba(db, left_rid, right_rid, left_marking_map, right_marking_map);
  613. bool resolutions_given;
  614. parse_resolve_conflicts_opts
  615. (app.opts, left_rid, left_roster, right_rid, right_roster, result, resolutions_given);
  616. resolve_merge_conflicts(app.lua, app.opts, left_roster, right_roster,
  617. result, dba, resolutions_given);
  618. {
  619. dir_t moved_root = left_roster.root();
  620. moved_root->parent = the_null_node;
  621. moved_root->name = path_component();
  622. }
  623. // Write new files into the db.
  624. store_roster_merge_result(db, left_roster, right_roster, result,
  625. left_rid, right_rid, merged);
  626. }
  627. bool log_message_given;
  628. utf8 log_message;
  629. utf8 log_prefix = utf8((FL("propagate from branch '%s' (head %s)\n"
  630. " to branch '%s' (head %s)\n")
  631. % idx(args, 0)
  632. % *src_i
  633. % idx(args, 1)
  634. % *dst_i).str(),
  635. origin::internal);
  636. process_commit_message_args(app.opts, log_message_given, log_message, log_prefix);
  637. project.put_standard_certs_from_options(app.opts, app.lua,
  638. keys,
  639. merged,
  640. typecast_vocab<branch_name>(idx(args, 1)),
  641. log_message);
  642. guard.commit();
  643. P(F("[merged] %s") % merged);
  644. }
  645. updater.maybe_do_update();
  646. }
  647. CMD(propagate, "propagate", "", CMD_REF(tree),
  648. N_("SOURCE-BRANCH DEST-BRANCH"),
  649. N_("Merges from one branch to another asymmetrically"),
  650. "",
  651. options::opts::date | options::opts::author | options::opts::messages |
  652. options::opts::resolve_conflicts_opts)
  653. {
  654. if (args.size() != 2)
  655. throw usage(execid);
  656. args_vector a = args;
  657. a.push_back(arg_type());
  658. perform_merge_into_dir(app, make_command_id("tree merge_into_dir"), a);
  659. }
  660. CMD(merge_into_dir, "merge_into_dir", "", CMD_REF(tree),
  661. N_("SOURCE-BRANCH DEST-BRANCH DIR"),
  662. N_("Merges one branch into a subdirectory in another branch"),
  663. "",
  664. options::opts::date | options::opts::author | options::opts::messages |
  665. options::opts::resolve_conflicts_opts | options::opts::auto_update)
  666. {
  667. perform_merge_into_dir(app, execid, args);
  668. }
  669. CMD(merge_into_workspace, "merge_into_workspace", "", CMD_REF(tree),
  670. N_("OTHER-REVISION"),
  671. N_("Merges a revision into the current workspace's base revision"),
  672. N_("Merges OTHER-REVISION into the current workspace's base revision, "
  673. "and update the current workspace with the result. There can be no "
  674. "pending changes in the current workspace. Both OTHER-REVISION and "
  675. "the workspace's base revision will be recorded as parents on commit. "
  676. "The workspace's selected branch is not changed."),
  677. options::opts::move_conflicting_paths)
  678. {
  679. revision_id left_id, right_id;
  680. cached_roster left, right;
  681. shared_ptr<roster_t> working_roster = shared_ptr<roster_t>(new roster_t());
  682. if (args.size() != 1)
  683. throw usage(execid);
  684. database db(app);
  685. workspace work(app);
  686. project_t project(db);
  687. // Get the current state of the workspace.
  688. // This command cannot be applied to a workspace with more than one parent
  689. // (revs can have no more than two parents).
  690. revision_id working_rid;
  691. {
  692. parent_map parents;
  693. work.get_parent_rosters(db, parents);
  694. E(parents.size() == 1, origin::user,
  695. F("this command can only be used in a single-parent workspace"));
  696. temp_node_id_source nis;
  697. work.get_current_roster_shape(db, nis, *working_roster);
  698. work.update_current_roster_from_filesystem(*working_roster);
  699. E(parent_roster(parents.begin()) == *working_roster, origin::user,
  700. F("'%s' can only be used in a workspace with no pending changes") %
  701. join_words(execid)());
  702. left_id = parent_id(parents.begin());
  703. left = parent_cached_roster(parents.begin());
  704. revision_t working_rev;
  705. make_revision_for_workspace(parents, *working_roster, working_rev);
  706. calculate_ident(working_rev, working_rid);
  707. }
  708. complete(app.opts, app.lua, project, idx(args, 0)(), right_id);
  709. db.get_roster(right_id, right);
  710. E(!(left_id == right_id), origin::user,
  711. F("workspace is already at revision %s") % left_id);
  712. E(!is_ancestor(db, right_id, left_id), origin::user,
  713. F("revision %s is already an ancestor of your workspace") % right_id);
  714. E(!is_ancestor(db, left_id, right_id), origin::user,
  715. F("revision %s is a descendant of the workspace parent,\n"
  716. "did you mean 'mtn update -r %s'?") % right_id % right_id);
  717. P(F("[left] %s") % left_id);
  718. P(F("[right] %s") % right_id);
  719. set<revision_id> left_uncommon_ancestors, right_uncommon_ancestors;
  720. db.get_uncommon_ancestors(left_id, right_id,
  721. left_uncommon_ancestors,
  722. right_uncommon_ancestors);
  723. roster_merge_result merge_result;
  724. MM(merge_result);
  725. roster_merge(*left.first, *left.second, left_uncommon_ancestors,
  726. *right.first, *right.second, right_uncommon_ancestors,
  727. merge_result);
  728. revision_id lca_id;
  729. cached_roster lca;
  730. find_common_ancestor_for_merge(db, left_id, right_id, lca_id);
  731. db.get_roster(lca_id, lca);
  732. map<file_id, file_path> paths;
  733. get_content_paths(*working_roster, paths);
  734. content_merge_workspace_adaptor wca(db, lca_id, lca.first,
  735. *left.second, *right.second, paths);
  736. wca.cache_roster(working_rid, working_roster);
  737. resolve_merge_conflicts(app.lua, app.opts, *left.first, *right.first, merge_result, wca, false);
  738. // Make sure it worked...
  739. I(merge_result.is_clean());
  740. merge_result.roster.check_sane(true);
  741. // Construct the workspace revision.
  742. parent_map parents;
  743. safe_insert(parents, std::make_pair(left_id, left));
  744. safe_insert(parents, std::make_pair(right_id, right));
  745. revision_t merged_rev;
  746. make_revision_for_workspace(parents, merge_result.roster, merged_rev);
  747. // Note: the csets in merged_rev are _not_ suitable for submission to
  748. // perform_content_update, because content changes have been dropped.
  749. cset update;
  750. make_cset(*left.first, merge_result.roster, update);
  751. // small race condition here...
  752. work.perform_content_update(*left.first, merge_result.roster, update, wca, true,
  753. app.opts.move_conflicting_paths);
  754. work.put_work_rev(merged_rev);
  755. work.maybe_update_inodeprints(db);
  756. P(F("updated to result of merge\n"
  757. " [left] %s\n"
  758. "[right] %s\n")
  759. % left_id
  760. % right_id);
  761. }
  762. CMD(explicit_merge, "explicit_merge", "", CMD_REF(tree),
  763. N_("LEFT-REVISION RIGHT-REVISION DEST-BRANCH"),
  764. N_("Merges two explicitly given revisions"),
  765. N_("The results of the merge are placed on the branch specified by "
  766. "DEST-BRANCH."),
  767. options::opts::date | options::opts::author |
  768. options::opts::messages | options::opts::resolve_conflicts_opts |
  769. options::opts::auto_update)
  770. {
  771. database db(app);
  772. key_store keys(app);
  773. project_t project(db);
  774. revision_id left, right;
  775. branch_name branch;
  776. if (args.size() != 3)
  777. throw usage(execid);
  778. maybe_workspace_updater updater(app, project);
  779. complete(app.opts, app.lua, project, idx(args, 0)(), left);
  780. complete(app.opts, app.lua, project, idx(args, 1)(), right);
  781. branch = typecast_vocab<branch_name>(idx(args, 2));
  782. E(!(left == right), origin::user,
  783. F("%s and %s are the same revision, aborting")
  784. % left % right);
  785. E(!is_ancestor(db, left, right), origin::user,
  786. F("%s is already an ancestor of %s")
  787. % left % right);
  788. E(!is_ancestor(db, right, left), origin::user,
  789. F("%s is already an ancestor of %s")
  790. % right % left);
  791. // avoid failure after lots of work
  792. cache_user_key(app.opts, project, keys, app.lua);
  793. merge_two(app.opts, app.lua, project, keys,
  794. left, right, branch, string("explicit merge"),
  795. std::cout, false);
  796. updater.maybe_do_update();
  797. }
  798. namespace
  799. {
  800. namespace syms
  801. {
  802. symbol const ancestor("ancestor");
  803. symbol const left("left");
  804. symbol const right("right");
  805. }
  806. }
  807. static void
  808. show_conflicts_core (database & db,
  809. lua_hooks & lua,
  810. revision_id const & l_id,
  811. revision_id const & r_id,
  812. bool const basic_io,
  813. bool automate,
  814. std::ostream & output)
  815. {
  816. // Note that left and right are in the order specified on the command line.
  817. // They are not in lexical order as they are with other merge commands so
  818. // they may appear swapped here. The user may have done that deliberately,
  819. // especially via automate, so we don't sort them here.
  820. basic_io::stanza st;
  821. if (basic_io)
  822. {
  823. st.push_binary_pair(syms::left, l_id.inner());
  824. st.push_binary_pair(syms::right, r_id.inner());
  825. }
  826. else
  827. {
  828. P(F("[left] %s") % l_id);
  829. P(F("[right] %s") % r_id);
  830. }
  831. if (is_ancestor(db, l_id, r_id))
  832. {
  833. if (basic_io)
  834. {
  835. basic_io::printer pr;
  836. pr.print_stanza(st);
  837. output.write(pr.buf.data(), pr.buf.size());
  838. }
  839. else
  840. P(F("%s is an ancestor of %s; no merge is needed.")
  841. % l_id % r_id);
  842. return;
  843. }
  844. if (is_ancestor(db, r_id, l_id))
  845. {
  846. if (basic_io)
  847. {
  848. basic_io::printer pr;
  849. pr.print_stanza(st);
  850. output.write(pr.buf.data(), pr.buf.size());
  851. }
  852. else
  853. P(F("%s is an ancestor of %s; no merge is needed.")
  854. % r_id % l_id);
  855. return;
  856. }
  857. shared_ptr<roster_t> l_roster = shared_ptr<roster_t>(new roster_t());
  858. shared_ptr<roster_t> r_roster = shared_ptr<roster_t>(new roster_t());
  859. marking_map l_marking, r_marking;
  860. db.get_roster(l_id, *l_roster, l_marking);
  861. db.get_roster(r_id, *r_roster, r_marking);
  862. set<revision_id> l_uncommon_ancestors, r_uncommon_ancestors;
  863. db.get_uncommon_ancestors(l_id, r_id, l_uncommon_ancestors, r_uncommon_ancestors);
  864. roster_merge_result result;
  865. roster_merge(*l_roster, l_marking, l_uncommon_ancestors,
  866. *r_roster, r_marking, r_uncommon_ancestors,
  867. result);
  868. if (result.is_clean())
  869. {
  870. if (basic_io)
  871. {
  872. basic_io::printer pr;
  873. pr.print_stanza(st);
  874. output.write(pr.buf.data(), pr.buf.size());
  875. }
  876. if (!automate)
  877. P(F("0 conflicts"));
  878. }
  879. else
  880. {
  881. content_merge_database_adaptor adaptor(db, l_id, r_id,
  882. l_marking, r_marking);
  883. {
  884. basic_io::printer pr;
  885. st.push_binary_pair(syms::ancestor, adaptor.lca.inner());
  886. pr.print_stanza(st);
  887. output.write(pr.buf.data(), pr.buf.size());
  888. }
  889. // The basic_io routines in roster_merge.cc access these rosters via
  890. // the adaptor.
  891. adaptor.cache_roster (l_id, l_roster);
  892. adaptor.cache_roster (r_id, r_roster);
  893. result.report_missing_root_conflicts(*l_roster, *r_roster, adaptor, basic_io, output);
  894. result.report_invalid_name_conflicts(*l_roster, *r_roster, adaptor, basic_io, output);
  895. result.report_directory_loop_conflicts(*l_roster, *r_roster, adaptor, basic_io, output);
  896. result.report_orphaned_node_conflicts(*l_roster, *r_roster, adaptor, basic_io, output);
  897. result.report_multiple_name_conflicts(*l_roster, *r_roster, adaptor, basic_io, output);
  898. result.report_duplicate_name_conflicts(*l_roster, *r_roster, adaptor, basic_io, output);
  899. result.report_attribute_conflicts(*l_roster, *r_roster, adaptor, basic_io, output);
  900. result.report_file_content_conflicts(lua, *l_roster, *r_roster, adaptor, basic_io, output);
  901. if (!automate)
  902. {
  903. int const supported = result.count_supported_resolution();
  904. int const unsupported = result.count_unsupported_resolution();
  905. P(FP("%d conflict with supported resolutions.",
  906. "%d conflicts with supported resolutions.",
  907. supported) % supported);
  908. if (unsupported > 0)
  909. P(FP("warning: %d conflict with no supported resolutions.",
  910. "warning: %d conflicts with no supported resolutions.",
  911. unsupported) % unsupported);
  912. }
  913. }
  914. }
  915. CMD(show_conflicts, "show_conflicts", "", CMD_REF(informative), N_("REV REV"),
  916. N_("Shows what conflicts need resolution between two revisions"),
  917. N_("The conflicts are calculated based on the two revisions given in "
  918. "the REV parameters."),
  919. options::opts::none)
  920. {
  921. database db(app);
  922. project_t project(db);
  923. if (args.size() != 2)
  924. throw usage(execid);
  925. revision_id l_id, r_id;
  926. complete(app.opts, app.lua, project, idx(args,0)(), l_id);
  927. complete(app.opts, app.lua, project, idx(args,1)(), r_id);
  928. show_conflicts_core(db, app.lua, l_id, r_id,
  929. false, // basic_io
  930. false, // automate
  931. std::cout);
  932. }
  933. static void get_conflicts_rids(args_vector const & args,
  934. database & db,
  935. project_t & project,
  936. app_state & app,
  937. revision_id & left_rid,
  938. revision_id & right_rid)
  939. {
  940. if (args.empty())
  941. {
  942. // get ids from heads
  943. E(!app.opts.branch().empty(), origin::user,
  944. F("please specify a branch, with '--branch=BRANCH'"));
  945. set<revision_id> heads;
  946. project.get_branch_heads(app.opts.branch, heads,
  947. app.opts.ignore_suspend_certs);
  948. E(heads.size() >= 2, origin::user,
  949. F("branch '%s' has only 1 head; must be at least 2 for conflicts") % app.opts.branch);
  950. revpair p = find_heads_to_merge (db, heads);
  951. left_rid = p.first;
  952. right_rid = p.second;
  953. }
  954. else if (args.size() == 2)
  955. {
  956. // get ids from args
  957. complete(app.opts, app.lua, project, idx(args,0)(), left_rid);
  958. complete(app.opts, app.lua, project, idx(args,1)(), right_rid);
  959. }
  960. else
  961. E(false, origin::user, F("wrong argument count"));
  962. }
  963. // Name: show_conflicts
  964. // Arguments:
  965. // Two revision ids (optional, determined from the workspace if not given; there must be exactly two heads)
  966. // Added in: 8.0
  967. // Changed in: 9.0 (see monotone.texi for details)
  968. // Purpose: Prints the conflicts between two revisions, to aid in merging them.
  969. //
  970. // Output format: see monotone.texi
  971. //
  972. // Error conditions:
  973. //
  974. // If the revision IDs are unknown or invalid prints an error message to
  975. // stderr and exits with status 1.
  976. //
  977. // If revision ids are not given, and the current workspace does not have
  978. // two heads, prints an error message to stderr and exits with status 1.
  979. //
  980. CMD_AUTOMATE(show_conflicts, N_("[LEFT_REVID RIGHT_REVID]"),
  981. N_("Shows the conflicts between two revisions"),
  982. N_("If no arguments are given, LEFT_REVID and RIGHT_REVID default to the "
  983. "first two heads that would be chosen by the 'merge' command."),
  984. options::opts::branch | options::opts::ignore_suspend_certs)
  985. {
  986. database db(app);
  987. project_t project(db);
  988. revision_id l_id, r_id;
  989. get_conflicts_rids(args, db, project, app, l_id, r_id);
  990. show_conflicts_core(db, app.lua, l_id, r_id,
  991. true, // basic_io
  992. true, // automate
  993. output);
  994. }
  995. CMD(store, "store", "", CMD_REF(conflicts),
  996. "[LEFT_REVID RIGHT_REVID]",
  997. N_("Store the conflicts from merging two revisions"),
  998. (F("If no arguments are given, LEFT_REVID and RIGHT_REVID default to the "
  999. "first two heads that would be chosen by the 'merge' command. If "
  1000. "'--conflicts-file' is not given, '%s' is used.") % bookkeeping_conflicts_file).str(),
  1001. options::opts::branch | options::opts::conflicts_opts)
  1002. {
  1003. database db(app);
  1004. project_t project(db);
  1005. revision_id left_id, right_id;
  1006. workspace::require_workspace(F("conflicts file must be under '_MTN'"));
  1007. get_conflicts_rids(args, db, project, app, left_id, right_id);
  1008. std::ostringstream output;
  1009. show_conflicts_core(db, app.lua, left_id, right_id,
  1010. true, // basic_io
  1011. false, // automate
  1012. output);
  1013. data dat(output.str(), origin::internal);
  1014. write_data(app.opts.conflicts_file, dat);
  1015. P(F("stored in '%s'") % app.opts.conflicts_file);
  1016. }
  1017. CMD_AUTOMATE(file_merge, N_("LEFT_REVID LEFT_FILENAME RIGHT_REVID RIGHT_FILENAME"),
  1018. N_("Prints the results of the internal line merger, given two child revisions and file names"),
  1019. "",
  1020. options::opts::none)
  1021. {
  1022. // We would have liked to take arguments of ancestor, left, right revision
  1023. // and file ids; those are provided by show_conflicts and would save
  1024. // computing the common ancestor and searching for file names. But we need
  1025. // the file names to get the manual merge and file encoding attributes,
  1026. // and there is no way to go from file id to file name. And there is no
  1027. // way to specify the ancestor id for a merge adaptor; why should we trust
  1028. // the user?
  1029. E(args.size() == 4, origin::user,
  1030. F("wrong argument count"));
  1031. database db(app);
  1032. project_t project(db);
  1033. revision_id left_rid;
  1034. complete(app.opts, app.lua, project, idx(args,0)(), left_rid);
  1035. file_path const left_path = file_path_external(idx(args,1));
  1036. revision_id right_rid;
  1037. complete(app.opts, app.lua, project, idx(args,2)(), right_rid);
  1038. file_path const right_path = file_path_external(idx(args,3));
  1039. roster_t left_roster;
  1040. roster_t right_roster;
  1041. marking_map left_marking, right_marking;
  1042. db.get_roster(left_rid, left_roster, left_marking);
  1043. db.get_roster(right_rid, right_roster, right_marking);
  1044. content_merge_database_adaptor adaptor(db, left_rid, right_rid,
  1045. left_marking, right_marking);
  1046. const_file_t left_n = downcast_to_file_t(left_roster.get_node(left_path));
  1047. const_file_t right_n = downcast_to_file_t(right_roster.get_node(right_path));
  1048. revision_id ancestor_rid;
  1049. file_path ancestor_path;
  1050. file_id ancestor_fid;
  1051. shared_ptr<roster_t const> ancestor_roster;
  1052. adaptor.get_ancestral_roster(left_n->self, ancestor_rid, ancestor_roster);
  1053. ancestor_roster->get_file_details(left_n->self, ancestor_fid, ancestor_path);
  1054. content_merger cm(app.lua, *ancestor_roster, left_roster, right_roster, adaptor);
  1055. file_data ancestor_data, left_data, right_data, merge_data;
  1056. E(cm.attempt_auto_merge(ancestor_path, left_path, right_path,
  1057. ancestor_fid, left_n->content, right_n->content,
  1058. left_data, right_data, merge_data),
  1059. origin::user,
  1060. F("internal line merger failed"));
  1061. output << merge_data;
  1062. }
  1063. CMD(pluck, "pluck", "", CMD_REF(workspace), N_("[PATH...]"),
  1064. N_("Applies changes made at arbitrary places in history"),
  1065. N_("This command takes changes made at any point in history, and "
  1066. "edits your current workspace to include those changes. The end result "
  1067. "is identical to 'mtn diff -r FROM -r TO | patch -p0', except that "
  1068. "this command uses monotone's merger, and thus intelligently handles "
  1069. "renames, conflicts, and so on.\n"
  1070. "If one revision is given, applies the changes made in that revision "
  1071. "compared to its parent.\n"
  1072. "If two revisions are given, applies the changes made to get from the "
  1073. "first revision to the second."),
  1074. options::opts::revision | options::opts::depth | options::opts::exclude |
  1075. options::opts::move_conflicting_paths)
  1076. {
  1077. database db(app);
  1078. workspace work(app);
  1079. project_t project(db);
  1080. // Work out our arguments
  1081. revision_id from_rid, to_rid;
  1082. if (app.opts.revision.size() == 1)
  1083. {
  1084. complete(app.opts, app.lua, project, idx(app.opts.revision, 0)(), to_rid);
  1085. std::set<revision_id> parents;
  1086. db.get_revision_parents(to_rid, parents);
  1087. E(parents.size() == 1, origin::user,
  1088. F("revision %s is a merge.\n"
  1089. "To apply the changes relative to one of its parents, use:\n"
  1090. " %s pluck -r PARENT -r %s")
  1091. % to_rid
  1092. % prog_name
  1093. % to_rid);
  1094. from_rid = *parents.begin();
  1095. }
  1096. else if (app.opts.revision.size() == 2)
  1097. {
  1098. complete(app.opts, app.lua, project, idx(app.opts.revision, 0)(), from_rid);
  1099. complete(app.opts, app.lua, project, idx(app.opts.revision, 1)(), to_rid);
  1100. }
  1101. else
  1102. throw usage(execid);
  1103. E(!(from_rid == to_rid), origin::user, F("no changes to apply"));
  1104. // notionally, we have the situation
  1105. //
  1106. // from --> working
  1107. // | |
  1108. // V V
  1109. // to --> merged
  1110. //
  1111. // - from is the revision we start plucking from
  1112. // - to is the revision we stop plucking at
  1113. // - working is the current contents of the workspace
  1114. // - merged is the result of the plucking, and achieved by running a
  1115. // merge in the fictional graph seen above
  1116. //
  1117. // To perform the merge, we use the real from roster, and the real working
  1118. // roster, but synthesize a temporary 'to' roster. This ensures that the
  1119. // 'from', 'working' and 'base' rosters all use the same nid namespace,
  1120. // while any additions that happened between 'from' and 'to' should be
  1121. // considered as new nodes, even if the file that was added is in fact in
  1122. // 'working' already -- so 'to' needs its own namespace. (Among other
  1123. // things, it is impossible with our merge formalism to have the above
  1124. // graph with a node that exists in 'to' and 'working', but not 'from'.)
  1125. //
  1126. // finally, we take the cset from working -> merged, and apply that to the
  1127. // workspace
  1128. // and take the cset from the workspace's base, and write that to _MTN/work
  1129. // The node id source we'll use for the 'working' and 'to' rosters.
  1130. temp_node_id_source nis;
  1131. // Get the FROM roster
  1132. shared_ptr<roster_t> from_roster = shared_ptr<roster_t>(new roster_t());
  1133. MM(*from_roster);
  1134. db.get_roster(from_rid, *from_roster);
  1135. // Get the WORKING roster
  1136. shared_ptr<roster_t> working_roster = shared_ptr<roster_t>(new roster_t());
  1137. MM(*working_roster);
  1138. work.get_current_roster_shape(db, nis, *working_roster);
  1139. work.update_current_roster_from_filesystem(*working_roster);
  1140. // Get the FROM->TO cset...
  1141. cset from_to_to; MM(from_to_to);
  1142. cset from_to_to_excluded; MM(from_to_to_excluded);
  1143. {
  1144. roster_t to_true_roster;
  1145. db.get_roster(to_rid, to_true_roster);
  1146. node_restriction mask(args_to_paths(args),
  1147. args_to_paths(app.opts.exclude),
  1148. app.opts.depth,
  1149. *from_roster, to_true_roster,
  1150. ignored_file(work));
  1151. roster_t restricted_roster;
  1152. make_restricted_roster(*from_roster, to_true_roster,
  1153. restricted_roster, mask);
  1154. make_cset(*from_roster, restricted_roster, from_to_to);
  1155. make_cset(restricted_roster, to_true_roster, from_to_to_excluded);
  1156. }
  1157. E(!from_to_to.empty(), origin::user, F("no changes to be applied"));
  1158. // ...and use it to create the TO roster
  1159. shared_ptr<roster_t> to_roster = shared_ptr<roster_t>(new roster_t());
  1160. MM(*to_roster);
  1161. {
  1162. *to_roster = *from_roster;
  1163. editable_roster_base editable_to_roster(*to_roster, nis);
  1164. from_to_to.apply_to(editable_to_roster);
  1165. }
  1166. parent_map parents;
  1167. work.get_parent_rosters(db, parents);
  1168. revision_t working_rev;
  1169. revision_id working_rid;
  1170. make_revision_for_workspace(parents, *working_roster, working_rev);
  1171. calculate_ident(working_rev, working_rid);
  1172. // Now do the merge
  1173. roster_merge_result result;
  1174. marking_map left_markings, right_markings;
  1175. three_way_merge(from_rid, *from_roster,
  1176. working_rid, *working_roster,
  1177. to_rid, *to_roster,
  1178. result, left_markings, right_markings);
  1179. roster_t & merged_roster = result.roster;
  1180. map<file_id, file_path> paths;
  1181. get_content_paths(*working_roster, paths);
  1182. content_merge_workspace_adaptor wca(db, from_rid, from_roster,
  1183. left_markings, right_markings, paths);
  1184. wca.cache_roster(working_rid, working_roster);
  1185. // cache the synthetic to_roster under the to_rid so that the real
  1186. // to_roster is not fetched from the db which does not have temporary nids
  1187. wca.cache_roster(to_rid, to_roster);
  1188. resolve_merge_conflicts(app.lua, app.opts, *working_roster, *to_roster,
  1189. result, wca, false);
  1190. I(result.is_clean());
  1191. // temporary node ids may appear
  1192. merged_roster.check_sane(true);
  1193. // we apply the working to merged cset to the workspace
  1194. cset update;
  1195. MM(update);
  1196. make_cset(*working_roster, merged_roster, update);
  1197. E(!update.empty(), origin::no_fault, F("no changes were applied"));
  1198. work.perform_content_update(*working_roster, merged_roster, update, wca, true,
  1199. app.opts.move_conflicting_paths);
  1200. P(F("applied changes to workspace"));
  1201. // and record any remaining changes in _MTN/revision
  1202. revision_t remaining;
  1203. MM(remaining);
  1204. make_revision_for_workspace(parents, merged_roster, remaining);
  1205. // small race condition here...
  1206. work.put_work_rev(remaining);
  1207. // add a note to the user log file about what we did
  1208. {
  1209. utf8 log;
  1210. work.read_user_log(log);
  1211. std::string log_str = log();
  1212. if (!log_str.empty())
  1213. log_str += "\n";
  1214. if (from_to_to_excluded.empty())
  1215. log_str += (FL("applied changes from %s\n"
  1216. " through %s\n")

Large files files are truncated, but you can click here to view the full file