#
#
# patch "automate.cc"
# from [0ac8f649510d46dadc120ba6998d41db675d6afb]
# to [f0de26b518e13579e6ccc81b2d8d29eee03ce89b]
#
============================================================
--- automate.cc 0ac8f649510d46dadc120ba6998d41db675d6afb
+++ automate.cc f0de26b518e13579e6ccc81b2d8d29eee03ce89b
@@ -1,4 +1,4 @@
-// Copyright (C) 2004 Nathaniel Smith
+// Copyright (C) 2004, 2007 Nathaniel Smith
//
// This program is made available under the GNU GPL version 2.0 or
// greater. See the accompanying file COPYING for details.
@@ -93,7 +93,7 @@ AUTOMATE(ancestors, N_("REV1 [REV2 [REV3
{
N(args.size() > 0,
F("wrong argument count"));
-
+
set ancestors;
vector frontier;
for (vector::const_iterator i = args.begin(); i != args.end(); ++i)
@@ -214,7 +214,7 @@ AUTOMATE(erase_ancestors, N_("[REV1 [REV
// format: ('attr', name, value), ('state', [unchanged|changed|added|dropped])
// occurs: zero or more times
//
-// Error conditions: If the file name has no attributes, prints only the
+// Error conditions: If the file name has no attributes, prints only the
// format version, if the file is unknown, escalates
AUTOMATE(attributes, N_("FILE"), options::opts::none)
{
@@ -245,20 +245,20 @@ AUTOMATE(attributes, N_("FILE"), options
// create the printer
basic_io::printer pr;
-
+
// print the format version
basic_io::stanza st;
st.push_str_pair(basic_io::syms::format_version, "1");
pr.print_stanza(st);
-
+
// the current node holds all current attributes (unchanged and new ones)
node_t n = current.get_node(path);
- for (full_attr_map_t::const_iterator i = n->attrs.begin();
+ for (full_attr_map_t::const_iterator i = n->attrs.begin();
i != n->attrs.end(); ++i)
{
std::string value(i->second.second());
std::string state("unchanged");
-
+
// if if the first value of the value pair is false this marks a
// dropped attribute
if (!i->second.first)
@@ -268,16 +268,16 @@ AUTOMATE(attributes, N_("FILE"), options
// because if it is dropped there as well it was already deleted
// in any previous revision
I(base.has_node(path));
-
+
node_t prev_node = base.get_node(path);
-
+
// find the attribute in there
full_attr_map_t::const_iterator j = prev_node->attrs.find(i->first);
I(j != prev_node->attrs.end());
-
+
// was this dropped before? then ignore it
if (!j->second.first) { continue; }
-
+
state = "dropped";
// output the previous (dropped) value later
value = j->second.second();
@@ -288,20 +288,20 @@ AUTOMATE(attributes, N_("FILE"), options
if (base.has_node(path))
{
node_t prev_node = base.get_node(path);
- full_attr_map_t::const_iterator j =
+ full_attr_map_t::const_iterator j =
prev_node->attrs.find(i->first);
// attribute not found? this is new
if (j == prev_node->attrs.end())
{
state = "added";
}
- // check if this attribute has been changed
+ // check if this attribute has been changed
// (dropped and set again)
else if (i->second.second() != j->second.second())
{
state = "changed";
}
-
+
}
// its added since the whole node has been just added
else
@@ -309,14 +309,14 @@ AUTOMATE(attributes, N_("FILE"), options
state = "added";
}
}
-
+
basic_io::stanza st;
st.push_str_triple(basic_io::syms::attr, i->first(), value);
st.push_str_pair(symbol("state"), state);
pr.print_stanza(st);
}
-
- // print the output
+
+ // print the output
output.write(pr.buf.data(), pr.buf.size());
}
@@ -366,7 +366,7 @@ AUTOMATE(ancestry_difference, N_("NEW_RE
{
N(args.size() > 0,
F("wrong argument count"));
-
+
revision_id a;
set bs;
vector::const_iterator i = args.begin();
@@ -433,7 +433,7 @@ AUTOMATE(parents, N_("REV"), options::op
{
N(args.size() == 1,
F("wrong argument count"));
-
+
revision_id rid(idx(args, 0)());
N(app.db.revision_exists(rid), F("No such revision %s") % rid);
set parents;
@@ -458,7 +458,7 @@ AUTOMATE(children, N_("REV"), options::o
{
N(args.size() == 1,
F("wrong argument count"));
-
+
revision_id rid(idx(args, 0)());
N(app.db.revision_exists(rid), F("No such revision %s") % rid);
set children;
@@ -550,8 +550,8 @@ AUTOMATE(select, N_("SELECTOR"), options
output << *i << '\n';
}
-struct node_info
-{
+struct node_info
+{
bool exists;
node_id id;
path::status type;
@@ -596,7 +596,7 @@ static void
typedef std::map inventory_map;
static void
-inventory_rosters(roster_t const & old_roster,
+inventory_rosters(roster_t const & old_roster,
roster_t const & new_roster,
node_restriction const & mask,
inventory_map & inventory)
@@ -622,7 +622,7 @@ inventory_rosters(roster_t const & old_r
get_node_info(new_roster, sp, inventory[sp].new_node);
}
}
-
+
}
struct inventory_itemizer : public tree_walker
@@ -632,7 +632,7 @@ struct inventory_itemizer : public tree_
app_state & app;
inodeprint_map ipm;
- inventory_itemizer(path_restriction const & m, inventory_map & i, app_state & a) :
+ inventory_itemizer(path_restriction const & m, inventory_map & i, app_state & a) :
mask(m), inventory(i), app(a)
{
if (app.work.in_inodeprints_mode())
@@ -701,38 +701,33 @@ namespace
}
// Name: inventory
-// Arguments: none
+// Arguments: [PATH]...
// Added in: 1.0
+// Modified to basic_io in: 4.1
-// Purpose: Prints a summary of every file found in the workspace or its
-// associated base manifest. Each unique path is listed on a line
-// prefixed by three status characters and two numeric values used
-// for identifying renames. The three status characters are as
-// follows.
+// Purpose: Prints a summary of every file or directory found in the
+// workspace or its associated base manifest.
+
+// Output: basic_io format. For each item, three to six lines are output:
//
-// column 1 pre-state
-// ' ' the path was unchanged in the pre-state
-// 'D' the path was deleted from the pre-state
-// 'R' the path was renamed from the pre-state name
-// column 2 post-state
-// ' ' the path was unchanged in the post-state
-// 'R' the path was renamed to the post-state name
-// 'A' the path was added to the post-state
-// column 3 node-state
-// ' ' the node is unchanged from the current roster
-// 'P' the node is patched to a new version
-// 'U' the node is unknown and not included in the roster
-// 'I' the node is ignored and not included in the roster
-// 'M' the node is missing but is included in the roster
+// path ""
+// old_node "" "file | directory"
+// new_node "" "file | directory"
+// fs_type "file | directory | none"
+// status "ignored | known | missing | unknown"
+// changes "content | content attrs | attrs"
//
-// Output format: Each path is printed on its own line, prefixed by three
-// status characters as described above. The status is followed by a
-// single space and two numbers, each separated by a single space,
-// used for identifying renames. The numbers are followed by a
-// single space and then the pathname, which includes the rest of
-// the line. Directory paths are identified as ending with the "/"
-// character, file paths do not end in this character.
+// 'fs_type' gives the state of the item in the workspace filesystem.
//
+// 'old_node' and 'new_node' give the status of the item in the manifest.
+// The 'old_node' and 'new_node' lines are not output if the corresponding
+// node state is 'none'.
+//
+// 'changes' is not output if there are no changes.
+//
+// FIXME: 'dropped', 'renamed' are not explicitly labeled.
+// FIXME: whether an item needs to be committed is not clear.
+//
// Error conditions: If no workspace book keeping _MTN directory is found,
// prints an error message to stderr, and exits with status 1.
@@ -747,10 +742,10 @@ AUTOMATE(inventory, N_("[PATH]..."), opt
// see: http://www.venge.net/mtn-wiki/MultiParentWorkspaceFallout
N(parents.size() == 1,
F("this command can only be used in a single-parent workspace"));
-
+
roster_t new_roster, old_roster = parent_roster(parents.begin());
temp_node_id_source nis;
-
+
app.work.get_current_roster_shape(new_roster, nis);
inventory_map inventory;
@@ -759,13 +754,13 @@ AUTOMATE(inventory, N_("[PATH]..."), opt
node_restriction nmask(includes, excludes, app.opts.depth, old_roster, new_roster, app);
inventory_rosters(old_roster, new_roster, nmask, inventory);
-
+
path_restriction pmask(includes, excludes, app.opts.depth, app);
inventory_filesystem(pmask, inventory, app);
basic_io::printer pr;
- for (inventory_map::const_iterator i = inventory.begin(); i != inventory.end();
+ for (inventory_map::const_iterator i = inventory.begin(); i != inventory.end();
++i)
{
basic_io::stanza st;
@@ -822,6 +817,12 @@ AUTOMATE(inventory, N_("[PATH]..."), opt
{
if (item.new_node.exists)
st.push_str_pair(syms::status, "missing");
+
+ // FIXME: missing 'else'. For examples,
+ // see tests/automate_inventory:
+ // 'original' renamed to 'renamed'
+ // 'dropped' dropped
+ // Original output identified these.
}
else // exists on filesystem
{
@@ -829,7 +830,7 @@ AUTOMATE(inventory, N_("[PATH]..."), opt
{
if (app.lua.hook_ignore_file(i->first))
st.push_str_pair(syms::status, "ignored");
- else
+ else
st.push_str_pair(syms::status, "unknown");
}
else if (item.new_node.type != item.fs_type)
@@ -860,7 +861,7 @@ AUTOMATE(inventory, N_("[PATH]..."), opt
// we're interested in comparing the content and attributes of the current
// path in the new roster against their corresponding values in the old
// roster.
- //
+ //
// the new content hash comes from the filesystem since the new roster has
// not been updated. the new attributes can come directly from the new
// roster.
@@ -890,6 +891,8 @@ AUTOMATE(inventory, N_("[PATH]..."), opt
changes.push_back("attrs");
}
+ // FIXME: maybe indicate renamed, dropped, needs commit here?
+
if (!changes.empty())
st.push_str_multi(syms::changes, changes);
}
@@ -1372,7 +1375,7 @@ AUTOMATE(tags, N_("[BRANCH_PATTERN]"), o
globish incl("*");
bool filtering(false);
-
+
if (args.size() == 1) {
incl = globish(idx(args, 0)());
filtering = true;
@@ -1383,7 +1386,7 @@ AUTOMATE(tags, N_("[BRANCH_PATTERN]"), o
basic_io::stanza stz;
stz.push_str_pair(symbol("format_version"), "1");
prt.print_stanza(stz);
-
+
set tags;
app.get_project().get_tags(tags);
@@ -1392,7 +1395,7 @@ AUTOMATE(tags, N_("[BRANCH_PATTERN]"), o
{
set branches;
app.get_project().get_revision_branches(tag->ident, branches);
-
+
bool show(!filtering);
vector branch_names;
@@ -1401,7 +1404,7 @@ AUTOMATE(tags, N_("[BRANCH_PATTERN]"), o
{
if (app.lua.hook_ignore_branch(*branch))
continue;
-
+
if (!show && match((*branch)()))
show = true;
branch_names.push_back((*branch)());
@@ -1478,7 +1481,7 @@ AUTOMATE(genkey, N_("KEYID PASSPHRASE"),
keypair kp;
P(F("generating key-pair '%s'") % ident);
generate_key_pair(kp, passphrase);
- P(F("storing key-pair '%s' in %s/")
+ P(F("storing key-pair '%s' in %s/")
% ident % app.keys.get_key_dir());
app.keys.put_key_pair(ident, kp);
@@ -1532,7 +1535,7 @@ AUTOMATE(get_option, N_("OPTION"), optio
string opt = args[0]();
if (opt == "database")
- output << database_option << '\n';
+ output << database_option << '\n';
else if (opt == "branch")
output << branch_option << '\n';
else if (opt == "key")
@@ -1548,12 +1551,12 @@ AUTOMATE(get_option, N_("OPTION"), optio
// 1: a revision ID
// 2: a file name
// Added in: 3.1
-// Purpose: Returns a list of revision IDs in which the content
-// was most recently changed, relative to the revision ID specified
-// in argument 1. This equates to a content mark following
+// Purpose: Returns a list of revision IDs in which the content
+// was most recently changed, relative to the revision ID specified
+// in argument 1. This equates to a content mark following
// the *-merge algorithm.
//
-// Output format: Zero or more basic_io stanzas, each specifying a
+// Output format: Zero or more basic_io stanzas, each specifying a
// revision ID for which a content mark is set.
//
// Each stanza has exactly one entry:
@@ -1604,15 +1607,15 @@ AUTOMATE(get_content_changed, N_("REV FI
// 2: a file name (in the source revision)
// 3: a target revision ID
// Added in: 3.1
-// Purpose: Given a the file name in the source revision, a filename
-// will if possible be returned naming the file in the target revision.
-// This allows the same file to be matched between revisions, accounting
+// Purpose: Given a the file name in the source revision, a filename
+// will if possible be returned naming the file in the target revision.
+// This allows the same file to be matched between revisions, accounting
// for renames and other changes.
//
-// Output format: Zero or one basic_io stanzas. Zero stanzas will be
-// output if the file does not exist within the target revision; this is
+// Output format: Zero or one basic_io stanzas. Zero stanzas will be
+// output if the file does not exist within the target revision; this is
// not considered an error.
-// If the file does exist in the target revision, a single stanza with the
+// If the file does exist in the target revision, a single stanza with the
// following details is output.
//
// The stanza has exactly one entry:
@@ -1653,7 +1656,7 @@ AUTOMATE(get_corresponding_path, N_("REV
basic_io::stanza st;
old_roster.get_name(node->self, old_path);
file_path fp = file_path(old_path);
- st.push_file_pair(basic_io::syms::file, fp);
+ st.push_file_pair(basic_io::syms::file, fp);
prt.print_stanza(st);
}
output.write(prt.buf.data(), prt.buf.size());
@@ -1682,7 +1685,7 @@ AUTOMATE(put_file, N_("[FILEID] CONTENTS
{
file_data dat(idx(args, 0)());
calculate_ident(dat, sha1sum);
-
+
app.db.put_file(sha1sum, dat);
}
else if (args.size() == 2)
@@ -1809,7 +1812,7 @@ AUTOMATE(db_set, N_("DOMAIN NAME VALUE")
{
N(args.size() == 3,
F("wrong argument count"));
-
+
var_domain domain = var_domain(idx(args, 0)());
utf8 name = idx(args, 1);
utf8 value = idx(args, 2);