# # # patch "cmd_merging.cc" # from [d0cda85b132150409d50526aa1d38c001932866d] # to [e05ff152427c0ccc43f41a2df5b361ce5d0e05b5] # # patch "cmd_netsync.cc" # from [ec1d1888558e6ae358ade3ab83605091c7ecc86a] # to [17199b154899d9bfb5c99f02f1c9e6c5d8b1c9e5] # ============================================================ --- cmd_merging.cc d0cda85b132150409d50526aa1d38c001932866d +++ cmd_merging.cc e05ff152427c0ccc43f41a2df5b361ce5d0e05b5 @@ -128,13 +128,10 @@ pick_branch_for_update(revision_id chose return switched_branch; } -CMD(update, "update", "", CMD_REF(workspace), "", - N_("Updates the workspace"), - N_("This command modifies your workspace to be based off of a " - "different revision, preserving uncommitted changes as it does so. " - "If a revision is given, update the workspace to that revision. " - "If not, update the workspace to the head of the branch."), - options::opts::branch | options::opts::revision) +static void +update(app_state & app, commands::command_id const & execid, + args_vector const & args, std::ostream & output, + bool automate) { if (args.size() > 0) throw usage(execid); @@ -155,12 +152,16 @@ CMD(update, "update", "", CMD_REF(worksp N(!null_id(old_rid), F("this workspace is a new project; cannot update")); + if (automate) + output << app.opts.branchname() << "\n"; + // Figure out where we're going revision_id chosen_rid; if (app.opts.revision_selectors.size() == 0) { - P(F("updating along branch '%s'") % app.opts.branchname); + if (!automate) + P(F("updating along branch '%s'") % app.opts.branchname); set candidates; pick_update_candidates(old_rid, app, candidates); N(!candidates.empty(), @@ -174,7 +175,8 @@ CMD(update, "update", "", CMD_REF(worksp for (set::const_iterator i = candidates.begin(); i != candidates.end(); ++i) P(i18n_format(" %s") % describe_revision(app, *i)); - P(F("choose one with '%s update -r'") % ui.prog_name); + if (!automate) + P(F("choose one with '%s update -r'") % ui.prog_name); E(false, F("multiple update candidates remain after selection")); } chosen_rid = *(candidates.begin()); @@ -194,7 +196,13 @@ CMD(update, "update", "", CMD_REF(worksp if (old_rid == chosen_rid) { - P(F("already up to date at %s") % old_rid); + if (automate) + { + output << chosen_rid << "\n"; + output << app.opts.branchname() << "\n"; + } + else + P(F("already up to date at %s") % old_rid); // do still switch the workspace branch, in case they have used // update to switch branches. if (!app.opts.branchname().empty()) @@ -202,7 +210,10 @@ CMD(update, "update", "", CMD_REF(worksp return; } - P(F("selected update target %s") % chosen_rid); + if (automate) + output << chosen_rid << "\n"; + else + P(F("selected update target %s") % chosen_rid); // Fiddle around with branches, in an attempt to guess what the user // wants. @@ -210,6 +221,9 @@ CMD(update, "update", "", CMD_REF(worksp if (switched_branch) P(F("switching to branch %s") % app.opts.branchname()); + if (automate) + output << app.opts.branchname() << "\n"; + // Okay, we have a target, we have a branch, let's do this merge! // We have: @@ -275,11 +289,40 @@ CMD(update, "update", "", CMD_REF(worksp if (!app.opts.branchname().empty()) app.make_branch_sticky(); - if (switched_branch) - P(F("switched branch; next commit will use branch %s") % app.opts.branchname()); - P(F("updated to base revision %s") % chosen_rid); + if (!automate) + { + if (switched_branch) + P(F("switched branch; next commit will use branch %s") % app.opts.branchname()); + P(F("updated to base revision %s") % chosen_rid); + } } +CMD(update, "update", "", CMD_REF(workspace), "", + N_("Updates the workspace"), + N_("This command modifies your workspace to be based off of a " + "different revision, preserving uncommitted changes as it does so. " + "If a revision is given, update the workspace to that revision. " + "If not, update the workspace to the head of the branch."), + options::opts::branch | options::opts::revision) +{ + update(app, execid, args, std::cout, false); +} + +// output: +// \n +// \n +// \n +CMD_AUTOMATE(update, "", + N_("Updates the workspace"), + N_("This command modifies your workspace to be based off of a " + "different revision, preserving uncommitted changes as it does so. " + "If a revision is given, update the workspace to that revision. " + "If not, update the workspace to the head of the branch."), + options::opts::branch | options::opts::revision) +{ + update(app, execid, args, output, true); +} + // Subroutine of CMD(merge) and CMD(explicit_merge). Merge LEFT with RIGHT, // placing results onto BRANCH. Note that interactive_merge_and_store may // bomb out, and therefore so may this. @@ -342,10 +385,10 @@ merge_two(revision_id const & left, revi // since a single 'merge' command may perform arbitrarily many actual merges. // (Possibility: append the --message/--message-file text to the synthetic // log message constructed in merge_two().) -CMD(merge, "merge", "", CMD_REF(tree), "", - N_("Merges unmerged heads of a branch"), - "", - options::opts::branch | options::opts::date | options::opts::author) +static void +merge(app_state & app, commands::command_id const & execid, + args_vector const & args, std::ostream & output, + bool automate) { typedef std::pair revpair; typedef set::const_iterator rid_set_iter; @@ -362,11 +405,13 @@ CMD(merge, "merge", "", CMD_REF(tree), " N(heads.size() != 0, F("branch '%s' is empty") % app.opts.branchname); if (heads.size() == 1) { - P(F("branch '%s' is already merged") % app.opts.branchname); + if (!automate) + P(F("branch '%s' is already merged") % app.opts.branchname); return; } - P(FP("%d head on branch '%s'", "%d heads on branch '%s'", heads.size()) + if (!automate) + P(FP("%d head on branch '%s'", "%d heads on branch '%s'", heads.size()) % heads.size() % app.opts.branchname); map heads_for_ancestor; @@ -387,8 +432,11 @@ CMD(merge, "merge", "", CMD_REF(tree), " // A and B will be merged first, and then the result will be merged with C. while (heads.size() > 2) { - P(F("merge %d / %d:") % pass % todo); - P(F("calculating best pair of heads to merge next")); + if (!automate) + { + P(F("merge %d / %d:") % pass % todo); + P(F("calculating best pair of heads to merge next")); + } // For every pair of heads, determine their merge ancestor, and // remember the ancestor->head mapping. @@ -421,7 +469,7 @@ CMD(merge, "merge", "", CMD_REF(tree), " // corresponding pair of heads. revpair p = heads_for_ancestor[*ancestors.begin()]; - merge_two(p.first, p.second, app.opts.branchname, string("merge"), app, std::cout, false); + merge_two(p.first, p.second, app.opts.branchname, string("merge"), app, output, automate); ancestors.clear(); heads_for_ancestor.clear(); @@ -431,7 +479,7 @@ CMD(merge, "merge", "", CMD_REF(tree), " // Last one. I(pass == todo); - if (todo > 1) + if (todo > 1 && !automate) P(F("merge %d / %d:") % pass % todo); rid_set_iter i = heads.begin(); @@ -439,10 +487,26 @@ CMD(merge, "merge", "", CMD_REF(tree), " revision_id right = *i++; I(i == heads.end()); - merge_two(left, right, app.opts.branchname, string("merge"), app, std::cout, false); - P(F("note: your workspaces have not been updated")); + merge_two(left, right, app.opts.branchname, string("merge"), app, output, automate); + if (!automate) + P(F("note: your workspaces have not been updated")); } +CMD(merge, "merge", "", CMD_REF(tree), "", + N_("Merges unmerged heads of a branch"), + "", + options::opts::branch | options::opts::date | options::opts::author) +{ + merge(app, execid, args, std::cout, false); +} + +CMD_AUTOMATE(merge, "", + N_("Merges unmerged heads of a branch"), "", + options::opts::branch | options::opts::date | options::opts::author) +{ + merge(app, execid, args, output, true); +} + CMD(propagate, "propagate", "", CMD_REF(tree), N_("SOURCE-BRANCH DEST-BRANCH"), N_("Merges from one branch to another asymmetrically"), ============================================================ --- cmd_netsync.cc ec1d1888558e6ae358ade3ab83605091c7ecc86a +++ cmd_netsync.cc 17199b154899d9bfb5c99f02f1c9e6c5d8b1c9e5 @@ -173,6 +173,17 @@ CMD(push, "push", "", CMD_REF(network), include_pattern, exclude_pattern, app); } +CMD_AUTOMATE(push, + N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), + N_("Pushes branches to a netsync server"), + N_("This will push all branches that match the pattern given in PATTERN " + "to the netsync server at the address ADDRESS."), + options::opts::set_default | options::opts::exclude | + options::opts::key_to_push) +{ + commands::push_cmd.exec(app, execid, args); +} + CMD(pull, "pull", "", CMD_REF(network), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), N_("Pulls branches from a netsync server"), @@ -196,6 +207,16 @@ CMD(pull, "pull", "", CMD_REF(network), include_pattern, exclude_pattern, app); } +CMD_AUTOMATE(pull, + N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), + N_("Pulls branches from a netsync server"), + N_("This pulls all branches that match the pattern given in PATTERN " + "from the netsync server at the address ADDRESS."), + options::opts::set_default | options::opts::exclude) +{ + commands::pull_cmd.exec(app, execid, args); +} + CMD(sync, "sync", "", CMD_REF(network), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), N_("Synchronizes branches with a netsync server"), @@ -217,6 +238,17 @@ CMD(sync, "sync", "", CMD_REF(network), include_pattern, exclude_pattern, app); } +CMD_AUTOMATE(sync, + N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), + N_("Synchronizes branches with a netsync server"), + N_("This synchronizes branches that match the pattern given in PATTERN " + "with the netsync server at the address ADDRESS."), + options::opts::set_default | options::opts::exclude | + options::opts::key_to_push) +{ + commands::sync_cmd.exec(app, execid, args); +} + class dir_cleanup_helper { public: