# # # patch "asciik.cc" # from [d5f28c70d0433dec7d0db7e1f035ea8a12ebbdd2] # to [2ca02070a5f71e971d8f8b7d1b469b805274ce0a] # # patch "cmd.hh" # from [5c6809b9a65951b6e69d3bb80ff2d6d42781c511] # to [158e7df2f5aaded06648bb830cd7d82acf0a60f0] # # patch "cmd_automate.cc" # from [69aefb502195a4d228f1cc39045ee72d42958b84] # to [363c37841f31b7e61fec9779443aa218efd53309] # # patch "cmd_db.cc" # from [a897d7dfbaa499adc2c8279d0f051eaa30f4e635] # to [22ac874fd038665a578f75ce860712bfc4a95114] # # patch "cmd_diff_log.cc" # from [1b7f8c23e25beaa81669eefb504de8315b7fbd4d] # to [fbcf1046e6789577e9d8f954236a8fdf657342f4] # # patch "cmd_files.cc" # from [17de5623905f507598b21286d65d96870096e086] # to [5bca090dd1c5e2b2531137089e1fd7eaf666e08c] # # patch "cmd_key_cert.cc" # from [368ba5326304c4ddb7e403dc1df455d05ab31a73] # to [a38632db6e62dc38a7b7eb5daa84912260ebf81e] # # patch "cmd_list.cc" # from [0ff9de55b90f18b284382b82ebfd43b405567a41] # to [c0e7a014a3a139f198b2b16a05a63c5ae0a6ec1d] # # patch "cmd_merging.cc" # from [af61f02853172ea7a6c53cee6579c0220766d53d] # to [92b9d75fbebbdd0ec4b1ef0f53d83ec6273f021e] # # patch "cmd_netsync.cc" # from [85389e376de990a6beb16c7cef2a9508e58c460c] # to [44da67e276c89c807db24610ed3a0b2c3558d471] # # patch "cmd_othervcs.cc" # from [daf6234e9e5fa47816ab74830e2de1973fe44712] # to [ac8739443a005bac29fa25135c49dcee8f5a3b08] # # patch "cmd_packet.cc" # from [ff0d753e667e71cb26fa883ba005bed5925ee092] # to [b1244abb8ed7125ec335777c929496f177a05436] # # patch "cmd_ws_commit.cc" # from [981134c77ca685b9872bfffe1814efefb686a7f8] # to [e4c0dc4781e352c7fee257a0e15ca57214c8697d] # # patch "commands.cc" # from [b75ca8fe6164c20993fe90c5383ebc888e2eae98] # to [9c2de6b3b3ca5e47667bc0d2195e62410b059677] # # patch "monotone.cc" # from [c1d774218a91a191fcd1894c3fc02c9aa0747dcf] # to [2782860a666c0c8c6afad5b9eaf674ffa2f19991] # # patch "revision.cc" # from [94ffffda8ea5623d05fef8d062b2a4401599578d] # to [75a5757a70e4f194804406820e1faf3d4233a560] # # patch "sha1.cc" # from [aa27d3e16300ee842b3531913f2548c84b50c6b4] # to [df789445950009447e89614f2b5752b016f490d2] # ============================================================ --- asciik.cc d5f28c70d0433dec7d0db7e1f035ea8a12ebbdd2 +++ asciik.cc 2ca02070a5f71e971d8f8b7d1b469b805274ce0a @@ -366,7 +366,9 @@ CMD(asciik, N_("debug"), N_("SELECTOR"), } CMD(asciik, N_("debug"), N_("SELECTOR"), - N_("prints an ASCII representation of the graph"), options::opts::none) + N_("Prints an ASCII representation of the revisions' graph"), + N_("prints an ASCII representation of the graph"), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); ============================================================ --- cmd.hh 5c6809b9a65951b6e69d3bb80ff2d6d42781c511 +++ cmd.hh 158e7df2f5aaded06648bb830cd7d82acf0a60f0 @@ -28,17 +28,20 @@ namespace commands std::string name; std::string cmdgroup; std::string params_; + std::string abstract_; std::string desc_; bool use_workspace_options; options::options_type opts; command(std::string const & n, std::string const & g, std::string const & p, + std::string const & a, std::string const & d, bool u, options::options_type const & o); virtual ~command(); virtual std::string params(); + virtual std::string abstract(); virtual std::string desc(); virtual options::options_type get_options(std::vector const & args); virtual void exec(app_state & app, @@ -92,11 +95,11 @@ process_commit_message_args(bool & given app_state & app, utf8 message_prefix = utf8("")); -#define CMD(C, group, params, desc, opts) \ +#define CMD(C, group, params, abstract, desc, opts) \ namespace commands { \ struct cmd_ ## C : public command \ { \ - cmd_ ## C() : command(#C, group, params, desc, true, \ + cmd_ ## C() : command(#C, group, params, abstract, desc, true, \ options::options_type() | opts) \ {} \ virtual void exec(app_state & app, \ @@ -110,11 +113,11 @@ void commands::cmd_ ## C::exec(app_state // Use this for commands that want to define a params() function // instead of having a static description. (Good for "automate" // and possibly "list".) -#define CMD_WITH_SUBCMDS(C, group, desc, opts) \ +#define CMD_WITH_SUBCMDS(C, group, abstract, desc, opts) \ namespace commands { \ struct cmd_ ## C : public command \ { \ - cmd_ ## C() : command(#C, group, "", desc, true, \ + cmd_ ## C() : command(#C, group, "", abstract, desc, true, \ options::options_type() | opts) \ {} \ virtual void exec(app_state & app, \ @@ -130,11 +133,11 @@ void commands::cmd_ ## C::exec(app_state // Use this for commands that should specifically _not_ look for an // _MTN dir and load options from it. -#define CMD_NO_WORKSPACE(C, group, params, desc, opts) \ +#define CMD_NO_WORKSPACE(C, group, params, abstract, desc, opts) \ namespace commands { \ struct cmd_ ## C : public command \ { \ - cmd_ ## C() : command(#C, group, params, desc, false, \ + cmd_ ## C() : command(#C, group, params, abstract, desc, false, \ options::options_type() | opts) \ {} \ virtual void exec(app_state & app, \ @@ -151,6 +154,7 @@ namespace commands { { \ cmd_ ## C() : command(#C, realcommand##_cmd.cmdgroup, \ realcommand##_cmd.params_, \ + realcommand##_cmd.abstract_, \ realcommand##_cmd.desc_, true, \ realcommand##_cmd.opts) \ {} \ ============================================================ --- cmd_automate.cc 69aefb502195a4d228f1cc39045ee72d42958b84 +++ cmd_automate.cc 363c37841f31b7e61fec9779443aa218efd53309 @@ -375,6 +375,7 @@ CMD_WITH_SUBCMDS(automate, N_("automatio CMD_WITH_SUBCMDS(automate, N_("automation"), + N_("Interface for scripted execution"), N_("automation interface"), options::opts::none) { ============================================================ --- cmd_db.cc a897d7dfbaa499adc2c8279d0f051eaa30f4e635 +++ cmd_db.cc 22ac874fd038665a578f75ce860712bfc4a95114 @@ -61,6 +61,7 @@ CMD(db, N_("database"), "rosterify\n" "regenerate_caches\n" "set_epoch BRANCH EPOCH\n"), + N_("Manipulates database state"), N_("manipulate database state"), options::opts::drop_attr) { @@ -122,6 +123,7 @@ CMD(set, N_("vars"), N_("DOMAIN NAME VAL } CMD(set, N_("vars"), N_("DOMAIN NAME VALUE"), + N_("Sets a database variable"), N_("set the database variable NAME to VALUE, in domain DOMAIN"), options::opts::none) { @@ -138,6 +140,7 @@ CMD(unset, N_("vars"), N_("DOMAIN NAME") } CMD(unset, N_("vars"), N_("DOMAIN NAME"), + N_("Unsets a database variable"), N_("remove the database variable NAME in domain DOMAIN"), options::opts::none) { @@ -155,6 +158,7 @@ CMD(complete, N_("informative"), N_("(re } CMD(complete, N_("informative"), N_("(revision|file|key) PARTIAL-ID"), + N_("Completes a partial identifier"), N_("complete partial id"), options::opts::verbose) { @@ -203,6 +207,7 @@ CMD(test_migration_step, hidden_group(), } CMD(test_migration_step, hidden_group(), "SCHEMA", + "Runs one step of migration on the specified database", "run one step of migration - from SCHEMA to its successor -\n" "on the specified database", options::opts::none) { ============================================================ --- cmd_diff_log.cc 1b7f8c23e25beaa81669eefb504de8315b7fbd4d +++ cmd_diff_log.cc fbcf1046e6789577e9d8f954236a8fdf657342f4 @@ -469,6 +469,7 @@ CMD(diff, N_("informative"), N_("[PATH]. } CMD(diff, N_("informative"), N_("[PATH]..."), + N_("Shows current differences"), N_("show current diffs on stdout.\n" "If one revision is given, the diff between the workspace and\n" "that revision is shown. If two revisions are given, the diff between\n" @@ -598,6 +599,7 @@ CMD(log, N_("informative"), N_("[FILE] . rev_cmp> frontier_t; CMD(log, N_("informative"), N_("[FILE] ..."), + N_("Prints history in reverse order"), N_("print history in reverse order (filtering by 'FILE'). If one or more\n" "revisions are given, use them as a starting point."), options::opts::last | options::opts::next ============================================================ --- cmd_files.cc 17de5623905f507598b21286d65d96870096e086 +++ cmd_files.cc 5bca090dd1c5e2b2531137089e1fd7eaf666e08c @@ -26,7 +26,10 @@ using std::vector; // fload, fmerge, and fdiff are simple commands for debugging the line // merger. -CMD(fload, N_("debug"), "", N_("load file contents into db"), options::opts::none) +CMD(fload, N_("debug"), "", + N_("Loads a file's contents into the database"), + N_("load file contents into db"), + options::opts::none) { data dat; read_data_stdin(dat); @@ -42,6 +45,7 @@ CMD(fmerge, N_("debug"), N_(" "), + N_("Merges 3 files and outputs the result"), N_("merge 3 files and output result"), options::opts::none) { @@ -79,6 +83,7 @@ CMD(fdiff, N_("debug"), N_("SRCNAME DEST } CMD(fdiff, N_("debug"), N_("SRCNAME DESTNAME SRCID DESTID"), + N_("Differences 2 files and outputs the result"), N_("diff 2 files and output result"), options::opts::diff_options) { @@ -115,6 +120,7 @@ CMD(annotate, N_("informative"), N_("PAT } CMD(annotate, N_("informative"), N_("PATH"), + N_("Prints an annotated copy of a file"), N_("print annotated copy of the file from REVISION"), options::opts::revision | options::opts::brief) { @@ -183,6 +189,7 @@ CMD(identify, N_("debug"), N_("[PATH]"), } CMD(identify, N_("debug"), N_("[PATH]"), + N_("Calculates the identity of a file or stdin"), N_("calculate identity of PATH or stdin"), options::opts::none) { @@ -246,6 +253,7 @@ CMD(cat, N_("informative"), CMD(cat, N_("informative"), N_("FILENAME"), + N_("Prints a file from the database"), N_("write file from database to stdout"), options::opts::revision) { ============================================================ --- cmd_key_cert.cc 368ba5326304c4ddb7e403dc1df455d05ab31a73 +++ cmd_key_cert.cc a38632db6e62dc38a7b7eb5daa84912260ebf81e @@ -29,7 +29,9 @@ using Botan::RSA_PrivateKey; using Botan::Pipe; using Botan::RSA_PrivateKey; -CMD(genkey, N_("key and cert"), N_("KEYID"), N_("generate an RSA key-pair"), +CMD(genkey, N_("key and cert"), N_("KEYID"), + N_("Generates an RSA key-pair"), + N_("generate an RSA key-pair"), options::opts::none) { if (args.size() != 1) @@ -56,7 +58,9 @@ CMD(dropkey, N_("key and cert"), N_("KEY } CMD(dropkey, N_("key and cert"), N_("KEYID"), - N_("drop a public and private key"), options::opts::none) + N_("Drops a public and/or private key"), + N_("drop a public and private key"), + options::opts::none) { bool key_deleted = false; @@ -96,6 +100,7 @@ CMD(passphrase, N_("key and cert"), N_(" } CMD(passphrase, N_("key and cert"), N_("KEYID"), + N_("Changes the passphrase of a private RSA key"), N_("change passphrase of a private RSA key"), options::opts::none) { @@ -118,6 +123,7 @@ CMD(ssh_agent_export, N_("key and cert") CMD(ssh_agent_export, N_("key and cert"), N_("[FILENAME]"), + N_("Export a private key for use with ssh-agent"), N_("export your monotone key for use with ssh-agent"), options::opts::none) { @@ -156,6 +162,7 @@ CMD(ssh_agent_add, N_("key and cert"), " } CMD(ssh_agent_add, N_("key and cert"), "", + N_("Adds a private key to ssh-agent"), N_("Add your monotone key to ssh-agent"), options::opts::none) { @@ -172,7 +179,9 @@ CMD(cert, N_("key and cert"), N_("REVISI } CMD(cert, N_("key and cert"), N_("REVISION CERTNAME [CERTVAL]"), - N_("create a cert for a revision"), options::opts::none) + N_("Creates a certificate for a revision"), + N_("create a cert for a revision"), + options::opts::none) { if ((args.size() != 3) && (args.size() != 2)) throw usage(name); @@ -204,6 +213,7 @@ CMD(trusted, N_("key and cert"), CMD(trusted, N_("key and cert"), N_("REVISION NAME VALUE SIGNER1 [SIGNER2 [...]]"), + N_("Tests whether a hypothetical certificate would be trusted"), N_("test whether a hypothetical cert would be trusted\n" "by current settings"), options::opts::none) @@ -251,7 +261,9 @@ CMD(tag, N_("review"), N_("REVISION TAGN } CMD(tag, N_("review"), N_("REVISION TAGNAME"), - N_("put a symbolic tag cert on a revision"), options::opts::none) + N_("Puts a symbolic tag certificate on a revision"), + N_("put a symbolic tag cert on a revision"), + options::opts::none) { if (args.size() != 2) throw usage(name); @@ -263,7 +275,9 @@ CMD(testresult, N_("review"), N_("ID (pa CMD(testresult, N_("review"), N_("ID (pass|fail|true|false|yes|no|1|0)"), - N_("note the results of running a test on a revision"), options::opts::none) + N_("Notes the results of running a test on a revision"), + N_("note the results of running a test on a revision"), + options::opts::none) { if (args.size() != 2) throw usage(name); @@ -275,6 +289,7 @@ CMD(approve, N_("review"), N_("REVISION" CMD(approve, N_("review"), N_("REVISION"), + N_("Approves a particular revision"), N_("approve of a particular revision"), options::opts::branch) { @@ -289,7 +304,9 @@ CMD(comment, N_("review"), N_("REVISION } CMD(comment, N_("review"), N_("REVISION [COMMENT]"), - N_("comment on a particular revision"), options::opts::none) + N_("Comments on a particular revision"), + N_("comment on a particular revision"), + options::opts::none) { if (args.size() != 1 && args.size() != 2) throw usage(name); ============================================================ --- cmd_list.cc 0ff9de55b90f18b284382b82ebfd43b405567a41 +++ cmd_list.cc c0e7a014a3a139f198b2b16a05a63c5ae0a6ec1d @@ -489,6 +489,7 @@ CMD(list, N_("informative"), "ignored\n" "missing\n" "changed"), + N_("Shows database objects"), N_("show database objects, or the current workspace manifest, \n" "or known, unknown, intentionally ignored, missing, or \n" "changed-state files"), ============================================================ --- cmd_merging.cc af61f02853172ea7a6c53cee6579c0220766d53d +++ cmd_merging.cc 92b9d75fbebbdd0ec4b1ef0f53d83ec6273f021e @@ -127,6 +127,7 @@ CMD(update, N_("workspace"), "", } CMD(update, N_("workspace"), "", + N_("Updates the workspace"), N_("update workspace.\n" "This command modifies your workspace to be based off of a\n" "different revision, preserving uncommitted changes as it does so.\n" @@ -329,7 +330,9 @@ 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, N_("tree"), "", N_("merge unmerged heads of branch"), +CMD(merge, N_("tree"), "", + N_("Merges unmerged heads of a branch"), + N_("merge unmerged heads of branch"), options::opts::branch | options::opts::date | options::opts::author) { typedef std::pair revpair; @@ -429,6 +432,7 @@ CMD(propagate, N_("tree"), N_("SOURCE-BR } CMD(propagate, N_("tree"), N_("SOURCE-BRANCH DEST-BRANCH"), + N_("Merges from one branch to another asymmetrically"), N_("merge from one branch to another asymmetrically"), options::opts::date | options::opts::author | options::opts::message | options::opts::msgfile) { @@ -440,6 +444,7 @@ CMD(merge_into_dir, N_("tree"), N_("SOUR } CMD(merge_into_dir, N_("tree"), N_("SOURCE-BRANCH DEST-BRANCH DIR"), + N_("Merges one branch into a subdirectory in another branch"), N_("merge one branch into a subdirectory in another branch"), options::opts::date | options::opts::author | options::opts::message | options::opts::msgfile) { @@ -597,6 +602,7 @@ CMD(merge_into_workspace, N_("tree"), CMD(merge_into_workspace, N_("tree"), N_("OTHER-REVISION"), + N_("Merges a revision into the current workspace's base revision"), N_("Merge OTHER-REVISION into the current workspace's base revision, " "and update the current workspace with the result. There can be no " "pending changes in the current workspace. Both OTHER-REVISION and " @@ -690,6 +696,7 @@ CMD(explicit_merge, N_("tree"), CMD(explicit_merge, N_("tree"), N_("LEFT-REVISION RIGHT-REVISION DEST-BRANCH"), + N_("Merges two explicitly given revisions"), N_("merge two explicitly given revisions, " "placing result in given branch"), options::opts::date | options::opts::author) @@ -715,6 +722,7 @@ CMD(show_conflicts, N_("informative"), N } CMD(show_conflicts, N_("informative"), N_("REV REV"), + N_("Shows what conflicts would need to be resolved"), N_("Show what conflicts would need to be resolved " "to merge the given revisions."), options::opts::branch | options::opts::date | options::opts::author) @@ -756,6 +764,7 @@ CMD(pluck, N_("workspace"), N_("[-r FROM } CMD(pluck, N_("workspace"), N_("[-r FROM] -r TO [PATH...]"), + N_("Applies changes made at arbitrary places in history"), N_("Apply changes made at arbitrary places in history to current workspace.\n" "This command takes changes made at any point in history, and\n" "edits your current workspace to include those changes. The end result\n" @@ -924,7 +933,9 @@ CMD(pluck, N_("workspace"), N_("[-r FROM } } -CMD(heads, N_("tree"), "", N_("show unmerged head revisions of branch"), +CMD(heads, N_("tree"), "", + N_("Shows unmerged head revisions of a branch"), + N_("show unmerged head revisions of branch"), options::opts::branch) { set heads; @@ -949,6 +960,7 @@ CMD(get_roster, N_("debug"), N_("[REVID] } CMD(get_roster, N_("debug"), N_("[REVID]"), + N_("Dumps the roster associated with a given identifier"), N_("dump the roster associated with the given REVID, " "or the workspace if no REVID is given"), options::opts::none) ============================================================ --- cmd_netsync.cc 85389e376de990a6beb16c7cef2a9508e58c460c +++ cmd_netsync.cc 44da67e276c89c807db24610ed3a0b2c3558d471 @@ -122,6 +122,7 @@ CMD(push, N_("network"), N_("[ADDRESS[:P } CMD(push, N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), + N_("Pushes branches to a netsync server"), N_("push branches matching PATTERN to netsync server at ADDRESS"), options::opts::set_default | options::opts::exclude | options::opts::key_to_push) @@ -137,6 +138,7 @@ CMD(pull, N_("network"), N_("[ADDRESS[:P } CMD(pull, N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), + N_("Pulls branches from a netsync server"), N_("pull branches matching PATTERN from netsync server at ADDRESS"), options::opts::set_default | options::opts::exclude) { @@ -153,6 +155,7 @@ CMD(sync, N_("network"), N_("[ADDRESS[:P } CMD(sync, N_("network"), N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), + N_("Synchronizes branches with a netsync server"), N_("sync branches matching PATTERN with netsync server at ADDRESS"), options::opts::set_default | options::opts::exclude | options::opts::key_to_push) @@ -195,6 +198,7 @@ CMD(clone, N_("network"), N_("ADDRESS[:P }; CMD(clone, N_("network"), N_("ADDRESS[:PORTNUMBER] [DIRECTORY]"), + N_("Checks out a revision from remote a database into a directory"), N_("check out a revision from remote database into directory.\n" "If a revision is given, that's the one that will be checked out.\n" "Otherwise, it will be the head of the branch supplied.\n" @@ -382,6 +386,7 @@ CMD_NO_WORKSPACE(serve, N_("network"), " }; CMD_NO_WORKSPACE(serve, N_("network"), "", + N_("Serves the database to connecting clients"), N_("serve the database to connecting clients"), options::opts::bind | options::opts::pidfile | options::opts::bind_stdio | options::opts::no_transport_auth) ============================================================ --- cmd_othervcs.cc daf6234e9e5fa47816ab74830e2de1973fe44712 +++ cmd_othervcs.cc ac8739443a005bac29fa25135c49dcee8f5a3b08 @@ -14,6 +14,7 @@ CMD(rcs_import, N_("debug"), N_("RCSFILE using std::vector; CMD(rcs_import, N_("debug"), N_("RCSFILE..."), + N_("Parses versions in RCS files"), N_("parse versions in RCS files\n" "this command doesn't reconstruct or import revisions." "you probably want cvs_import"), @@ -31,6 +32,7 @@ CMD(cvs_import, N_("rcs"), N_("CVSROOT") CMD(cvs_import, N_("rcs"), N_("CVSROOT"), + N_("Imports all versions in a CVS repository"), N_("import all versions in CVS repository"), options::opts::branch) { ============================================================ --- cmd_packet.cc ff0d753e667e71cb26fa883ba005bed5925ee092 +++ cmd_packet.cc b1244abb8ed7125ec335777c929496f177a05436 @@ -20,6 +20,7 @@ CMD(pubkey, N_("packet i/o"), N_("ID"), using std::vector; CMD(pubkey, N_("packet i/o"), N_("ID"), + N_("Prints a public key packet"), N_("write public key packet to stdout"), options::opts::none) { @@ -49,6 +50,7 @@ CMD(privkey, N_("packet i/o"), N_("ID"), } CMD(privkey, N_("packet i/o"), N_("ID"), + N_("Prints a private key packet"), N_("write private key packet to stdout"), options::opts::none) { @@ -129,6 +131,7 @@ CMD(read, N_("packet i/o"), "[FILE1 [FIL CMD(read, N_("packet i/o"), "[FILE1 [FILE2 [...]]]", + N_("Reads packets from files"), N_("read packets from files or stdin"), options::opts::none) { ============================================================ --- cmd_ws_commit.cc 981134c77ca685b9872bfffe1814efefb686a7f8 +++ cmd_ws_commit.cc e4c0dc4781e352c7fee257a0e15ca57214c8697d @@ -79,6 +79,7 @@ CMD(revert, N_("workspace"), N_("[PATH]. } CMD(revert, N_("workspace"), N_("[PATH]..."), + N_("Reverts files and/or directories"), N_("revert file(s), dir(s) or entire workspace (\".\")"), options::opts::depth | options::opts::exclude | options::opts::missing) { @@ -209,6 +210,7 @@ CMD(disapprove, N_("review"), N_("REVISI } CMD(disapprove, N_("review"), N_("REVISION"), + N_("Disapproves a particular revision"), N_("disapprove of a particular revision"), options::opts::branch | options::opts::messages | options::opts::date | options::opts::author) @@ -262,6 +264,7 @@ CMD(mkdir, N_("workspace"), N_("[DIRECTO } CMD(mkdir, N_("workspace"), N_("[DIRECTORY...]"), + N_("Creates directories and adds them to the workspace"), N_("create one or more directories and add them to the workspace"), options::opts::no_ignore) { @@ -306,6 +309,7 @@ CMD(add, N_("workspace"), N_("[PATH]..." } CMD(add, N_("workspace"), N_("[PATH]..."), + N_("Adds files to the workspace"), N_("add files to workspace"), options::opts::unknown | options::opts::no_ignore | options::opts::recursive) @@ -339,6 +343,7 @@ CMD(drop, N_("workspace"), N_("[PATH]... } CMD(drop, N_("workspace"), N_("[PATH]..."), + N_("Drops files from the workspace"), N_("drop files from workspace"), options::opts::bookkeep_only | options::opts::missing | options::opts::recursive) { @@ -371,6 +376,7 @@ CMD(rename, N_("workspace"), CMD(rename, N_("workspace"), N_("SRC DEST\n" "SRC1 [SRC2 [...]] DEST_DIR"), + N_("Renames entries in the workspace"), N_("rename entries in the workspace"), options::opts::bookkeep_only) { @@ -394,6 +400,7 @@ CMD(pivot_root, N_("workspace"), N_("NEW CMD(pivot_root, N_("workspace"), N_("NEW_ROOT PUT_OLD"), + N_("Renames the root directory"), N_("rename the root directory\n" "after this command, the directory that currently " "has the name NEW_ROOT\n" @@ -412,7 +419,9 @@ CMD(pivot_root, N_("workspace"), N_("NEW app.work.perform_pivot_root(new_root, put_old, app.opts.bookkeep_only); } -CMD(status, N_("informative"), N_("[PATH]..."), N_("show status of workspace"), +CMD(status, N_("informative"), N_("[PATH]..."), + N_("Shows workspace's status information"), + N_("show status of workspace"), options::opts::depth | options::opts::exclude) { roster_t new_roster; @@ -485,6 +494,7 @@ CMD(checkout, N_("tree"), N_("[DIRECTORY } CMD(checkout, N_("tree"), N_("[DIRECTORY]"), + N_("Checks out a revision from the database into a directory"), N_("check out a revision from database into directory.\n" "If a revision is given, that's the one that will be checked out.\n" "Otherwise, it will be the head of the branch (given or implicit).\n" @@ -593,7 +603,9 @@ ALIAS(co, checkout); ALIAS(co, checkout); -CMD(attr, N_("workspace"), N_("set PATH ATTR VALUE\nget PATH [ATTR]\ndrop PATH [ATTR]"), +CMD(attr, N_("workspace"), + N_("set PATH ATTR VALUE\nget PATH [ATTR]\ndrop PATH [ATTR]"), + N_("Manages file attributes"), N_("set, get or drop file attributes"), options::opts::none) { @@ -694,6 +706,7 @@ CMD(commit, N_("workspace"), N_("[PATH]. CMD(commit, N_("workspace"), N_("[PATH]..."), + N_("Commits workspace changes to the database"), N_("commit workspace to database"), options::opts::branch | options::opts::message | options::opts::msgfile | options::opts::date | options::opts::author | options::opts::depth @@ -943,6 +956,7 @@ CMD_NO_WORKSPACE(setup, N_("tree"), N_(" CMD_NO_WORKSPACE(setup, N_("tree"), N_("[DIRECTORY]"), + N_("Sets up a new workspace directory"), N_("setup a new workspace directory, default to current"), options::opts::branch) { @@ -966,6 +980,7 @@ CMD_NO_WORKSPACE(import, N_("tree"), N_( } CMD_NO_WORKSPACE(import, N_("tree"), N_("DIRECTORY"), + N_("Imports the contents of a directory into a branch"), N_("import the contents of the given directory tree into a given branch"), options::opts::branch | options::opts::revision | options::opts::message | options::opts::msgfile | @@ -1066,6 +1081,7 @@ CMD_NO_WORKSPACE(migrate_workspace, N_(" } CMD_NO_WORKSPACE(migrate_workspace, N_("tree"), N_("[DIRECTORY]"), + N_("Migrates a workspace directory's metadata to the latest format"), N_("migrate a workspace directory's metadata to the latest format; " "defaults to the current workspace"), options::opts::none) @@ -1079,7 +1095,9 @@ CMD_NO_WORKSPACE(migrate_workspace, N_(" app.work.migrate_ws_format(); } -CMD(refresh_inodeprints, N_("tree"), "", N_("refresh the inodeprint cache"), +CMD(refresh_inodeprints, N_("tree"), "", + N_("Refreshes the inodeprint cache"), + N_("refresh the inodeprint cache"), options::opts::none) { app.require_workspace(); ============================================================ --- commands.cc b75ca8fe6164c20993fe90c5383ebc888e2eae98 +++ commands.cc 9c2de6b3b3ca5e47667bc0d2195e62410b059677 @@ -7,6 +7,7 @@ // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. +#include #include #include #include @@ -68,11 +69,12 @@ namespace commands command::command(string const & n, string const & g, string const & p, + string const & a, string const & d, bool u, options::options_type const & o) - : name(n), cmdgroup(g), params_(p), desc_(d), use_workspace_options(u), - opts(o) + : name(n), cmdgroup(g), params_(p), abstract_(a), desc_(d), + use_workspace_options(u), opts(o) { if (cmds == NULL) cmds = new map; @@ -80,6 +82,7 @@ namespace commands } command::~command() {} std::string command::params() {return safe_gettext(params_.c_str());} + std::string command::abstract() {return safe_gettext(abstract_.c_str());} std::string command::desc() {return safe_gettext(desc_.c_str());} options::options_type command::get_options(vector const & args) { @@ -110,6 +113,34 @@ namespace commands using std::greater; using std::ostream; + static map cmdgroups; + + static void init_cmdgroups(void) + { + if (cmdgroups.empty()) + { +#define insert(id, abstract) \ + cmdgroups.insert(map::value_type(id, abstract)); + + insert("automation", N_("Commands that aid in scripted execution")); + insert("database", N_("Commands that manipulate the database")); + insert("debug", N_("Commands that aid in program debugging")); + insert("informative", N_("Commands for information retrieval")); + insert("key and cert", N_("Commands to manage keys and certificates")); + insert("network", N_("Commands that access the network")); + insert("packet i/o", N_("Commands for packet reading and writing")); + insert("rcs", N_("Commands for interaction with RCS and CVS")); + insert("review", N_("Commands to review revisions")); + insert("tree", N_("Commands to manipulate the tree")); + insert("vars", N_("Commands to manage persistent variables")); + insert("workspace", N_("Commands that deal with the workspace")); + +#undef insert + } + + assert(!cmdgroups.empty()); + } + bool operator<(command const & self, command const & other) { // *twitch* @@ -138,8 +169,8 @@ namespace commands } // no matched commands - N(matched.size() != 0, - F("unknown command '%s'") % cmd); + if (matched.size() == 0) + return ""; // one matched command if (matched.size() == 1) @@ -158,79 +189,182 @@ namespace commands return cmd; } - void explain_usage(string const & cmd, ostream & out) + string complete_command_group(string const & cmdgroup) { - map::const_iterator i; + init_cmdgroups(); - // try to get help on a specific command + if (cmdgroup.length() == 0 || cmdgroups.find(cmdgroup) != cmdgroups.end()) + return cmdgroup; - i = (*cmds).find(cmd); + L(FL("expanding command group '%s'") % cmdgroup); - if (i != (*cmds).end()) + vector matched; + + for (map::const_iterator i = cmdgroups.begin(); + i != cmdgroups.end(); ++i) { - string params = i->second->params(); - vector lines; - split_into_lines(params, lines); - for (vector::const_iterator j = lines.begin(); - j != lines.end(); ++j) - out << " " << i->second->name << ' ' << *j << '\n'; - split_into_lines(i->second->desc(), lines); - for (vector::const_iterator j = lines.begin(); - j != lines.end(); ++j) - out << " " << *j << '\n'; - out << '\n'; - return; + if (cmdgroup.length() < i->first.length()) + { + string prefix(i->first, 0, cmdgroup.length()); + if (cmdgroup == prefix) + matched.push_back(i->first); + } } - vector sorted; - out << _("commands:") << '\n'; - for (i = (*cmds).begin(); i != (*cmds).end(); ++i) + // no matched commands + if (matched.size() == 0) + return ""; + + // one matched command + if (matched.size() == 1) { - if (i->second->cmdgroup != hidden_group()) - sorted.push_back(i->second); + string completed = *matched.begin(); + L(FL("expanded command group to '%s'") % completed); + return completed; } - sort(sorted.begin(), sorted.end(), greater()); + // more than one matched command + string err = (F("command group '%s' has multiple ambiguous " + "expansions:") % cmdgroup).str(); + for (vector::iterator i = matched.begin(); + i != matched.end(); ++i) + err += ('\n' + *i); + W(i18n_format(err)); - string curr_group; + return cmdgroup; + } + + // Prints the abstract description of the given command or command group + // properly indented. The tag starts at column two. The description has + // to start, at the very least, two spaces after the tag's end position; + // this is given by the colabstract parameter. + static void describe(const string & tag, const string & abstract, + size_t colabstract, ostream & out) + { size_t col = 0; - size_t col2 = 0; - for (size_t i = 0; i < sorted.size(); ++i) + out << " " << tag << " "; + col += display_width(utf8(tag + " ")); + + // TODO: Properly wrap long lines. + + while (col++ < colabstract) + out << ' '; + out << abstract << std::endl; + } + + static void explain_cmdgroups(ostream & out ) + { + size_t colabstract = 0; + for (map::const_iterator i = cmdgroups.begin(); + i != cmdgroups.end(); i++) { - size_t cmp = display_width(utf8(safe_gettext(idx(sorted, i)->cmdgroup.c_str()))); - col2 = col2 > cmp ? col2 : cmp; + string const & name = (*i).first; + + size_t len = display_width(utf8(name + " ")); + if (colabstract < len) + colabstract = len; } - size_t maxcol = guess_terminal_width(); - for (size_t i = 0; i < sorted.size(); ++i) + out << "Command groups:" << std::endl << std::endl; + for (map::const_iterator i = cmdgroups.begin(); + i != cmdgroups.end(); i++) { - if (idx(sorted, i)->cmdgroup != curr_group) - { - curr_group = idx(sorted, i)->cmdgroup; - out << '\n'; - out << " " << safe_gettext(idx(sorted, i)->cmdgroup.c_str()); - col = display_width(utf8(safe_gettext(idx(sorted, i)->cmdgroup.c_str()))) + 2; - while (col++ < (col2 + 3)) - out << ' '; - } + string const & name = (*i).first; + string const & abstract = (*i).second; - // Start new line if the current command could make the previous - // one wrap. Indent it appropriately. - if (col + idx(sorted, i)->name.size() + 1 >= maxcol) + describe(name, abstract, colabstract, out); + } + } + + static void explain_cmdgroup_usage(string const & cmdgroup, ostream & out) + { + init_cmdgroups(); + + map::const_iterator grpi = cmdgroups.find(cmdgroup); + assert(grpi != cmdgroups.end()); + + size_t colabstract = 0; + vector sorted; + for (map::const_iterator i = (*cmds).begin(); + i != (*cmds).end(); ++i) + { + if (i->second->cmdgroup == cmdgroup) { - out << '\n'; - col = 0; - while (col++ < (col2 + 3)) - out << ' '; + sorted.push_back(i->second); + + size_t len = display_width(utf8(i->second->name + " ")); + if (colabstract < len) + colabstract = len; } + } - // Print the current command name. - out << ' ' << idx(sorted, i)->name; - col += idx(sorted, i)->name.size() + 1; + sort(sorted.begin(), sorted.end(), greater()); + + out << (*grpi).second << ":" << std::endl; + for (size_t i = 0; i < sorted.size(); ++i) + { + string const & name = idx(sorted, i)->name; + string const & abstract = idx(sorted, i)->abstract(); + + describe(name, abstract, colabstract, out); } - out << "\n\n"; } + static void explain_cmd_usage(string const & cmd, ostream & out) + { + map::const_iterator i; + + i = (*cmds).find(cmd); + assert(i != (*cmds).end()); + + out << F(safe_gettext("Syntax specific to 'mtn %s':")) % cmd + << std::endl << std::endl; + string params = i->second->params(); + vector lines; + split_into_lines(params, lines); + for (vector::const_iterator j = lines.begin(); + j != lines.end(); ++j) + out << " " << i->second->name << ' ' << *j << std::endl; + split_into_lines(i->second->desc(), lines); + for (vector::const_iterator j = lines.begin(); + j != lines.end(); ++j) + out << " " << *j << std::endl; + } + + void explain_usage(string const & cmd, ostream & out) + { + init_cmdgroups(); + + map::const_iterator cmditer; + map::const_iterator cmdgroupiter; + + cmditer = (*cmds).find(cmd); + cmdgroupiter = cmdgroups.find(cmd); + + if (cmditer != (*cmds).end()) + explain_cmd_usage(cmd, out); + else if (cmdgroupiter != cmdgroups.end()) + { + explain_cmdgroup_usage(cmd, out); + out << std::endl; + out << "For information on a specific command, type " + "'mtn help '." << std::endl; + } + else + { + assert(cmd.empty()); + + explain_cmdgroups(out); + out << std::endl; + out << "To see what commands are available in a group, type " + "'mtn help '." << std::endl; + out << "For information on a specific command, type " + "'mtn help '." << std::endl; + } + + out << std::endl; + } + int process(app_state & app, string const & cmd, vector const & args) { if ((*cmds).find(cmd) != (*cmds).end()) @@ -263,6 +397,8 @@ namespace commands } else { + N(!cmd.empty(), + F("unknown command '%s'") % cmd); return options::options_type(); } } @@ -282,7 +418,9 @@ CMD(help, N_("informative"), N_("command //////////////////////////////////////////////////////////////////////// CMD(help, N_("informative"), N_("command [ARGS...]"), - N_("display command help"), options::opts::none) + N_("Displays help about commands and options"), + N_("display command help"), + options::opts::none) { if (args.size() < 1) { @@ -291,15 +429,31 @@ CMD(help, N_("informative"), N_("command } string full_cmd = complete_command(idx(args, 0)()); - if ((*cmds).find(full_cmd) == (*cmds).end()) - throw usage(""); + string full_cmdgroup = complete_command_group(idx(args, 0)()); - app.opts.help = true; - throw usage(full_cmd); + if (cmdgroups.find(full_cmdgroup) != cmdgroups.end()) + { + app.opts.help = true; + throw usage(full_cmdgroup); + } + else if ((*cmds).find(full_cmd) != (*cmds).end()) + { + app.opts.help = true; + throw usage(full_cmd); + } + else + { + // No matched commands or command groups + N(!full_cmd.empty() && full_cmdgroup.empty(), + F("unknown command or command group '%s'") % idx(args, 0)()); + throw usage(""); + } } CMD(crash, hidden_group(), "{ N | E | I | exception | signal }", - "trigger the specified kind of crash", options::opts::none) + "Triggers the specified kind of crash", + "trigger the specified kind of crash", + options::opts::none) { if (args.size() != 1) throw usage(name); ============================================================ --- monotone.cc c1d774218a91a191fcd1894c3fc02c9aa0747dcf +++ monotone.cc 2782860a666c0c8c6afad5b9eaf674ffa2f19991 @@ -134,7 +134,11 @@ string read_options(options & opts, vect // consume the command, and perform completion if necessary string cmd; if (!opts.args.empty()) - cmd = commands::complete_command(idx(opts.args, 0)()); + { + cmd = commands::complete_command(idx(opts.args, 0)()); + N(!cmd.empty(), + F("unknown command '%s'") % cmd); + } // reparse options, now that we know what command-specific // options are allowed. ============================================================ --- revision.cc 94ffffda8ea5623d05fef8d062b2a4401599578d +++ revision.cc 75a5757a70e4f194804406820e1faf3d4233a560 @@ -1804,7 +1804,9 @@ regenerate_caches(app_state & app) P(F("finished regenerating cached rosters and heights")); } -CMD(rev_height, hidden_group(), N_("REV"), "show the height for REV", +CMD(rev_height, hidden_group(), N_("REV"), + "Shows a revision's height", + "show the height for REV", options::opts::none) { if (args.size() != 1) ============================================================ --- sha1.cc aa27d3e16300ee842b3531913f2548c84b50c6b4 +++ sha1.cc df789445950009447e89614f2b5752b016f490d2 @@ -92,7 +92,10 @@ void hook_botan_sha1() Botan::global_state().add_engine(new Monotone_SHA1_Engine); } -CMD(benchmark_sha1, hidden_group(), "", "benchmark SHA-1 cores", options::opts::none) +CMD(benchmark_sha1, hidden_group(), "", + "Benchmarks SHA-1 cores", + "benchmark SHA-1 cores", + options::opts::none) { P(F("Benchmarking %s SHA-1 cores") % registry().size()); int mebibytes = 100;