# # patch "ChangeLog" # from [6e22e889153a1f364903affbebb2740b5c88ce12] # to [d9bae9e86052243f61532ffeb48b0821f153587f] # # patch "commands.cc" # from [0f3716f5547c7cb58ee746eb730116642cfbc57f] # to [6763f5d11e2640faf05633b500e19d67a8ab32d3] # # patch "monotone.texi" # from [46a721660c81dc2ff3db7ad2dc211accb2f04475] # to [ca65b5dcbdb18c4636c353478b98098b3a046198] # # patch "tests/t_inventory.at" # from [bd593ada60d57c005007137cccec56d172955290] # to [2cfa97b7d12c1bf751f7f8aefb64c7d566a2e8e1] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,13 @@ +2005-04-27 Derek Scherger + + * commands.cc (ls_unknown): remove unneeded braces + (struct inventory_item): new struct for tracking inventories + (print_inventory): removed old output functions + (inventory_paths): new functions for paths, data and renames + (inventory): rework to display two column status codes + * monotone.texi (Informative): update for new status codes + * tests/t_inventory.at: update for two column status codes + 2005-04-25 Nathaniel Smith * automate.cc (automate_parents, automate_children) --- commands.cc +++ commands.cc @@ -2064,15 +2064,10 @@ if (want_ignored) for (path_set::const_iterator i = ignored.begin(); i != ignored.end(); ++i) - { - cout << *i << endl; - } + cout << *i << endl; else for (path_set::const_iterator i = unknown.begin(); i != unknown.end(); ++i) - { - cout << *i << endl; - } - + cout << *i << endl; } static void @@ -2109,37 +2104,73 @@ } } +struct inventory_item +{ + enum pstat + { UNCHANGED_PATH, ADDED_PATH, DROPPED_PATH, RENAMED_PATH, UNKNOWN_PATH, IGNORED_PATH } + path_status; + + enum dstat + { UNCHANGED_DATA, PATCHED_DATA, MISSING_DATA } + data_status; + + enum ptype + { FILE, DIRECTORY } + path_type; + + file_path old_path; + + inventory_item(): + path_status(UNCHANGED_PATH), data_status(UNCHANGED_DATA), path_type(FILE), old_path() {} +}; + +typedef std::map inventory_map; + static void -print_inventory(std::string const & status, - std::string const & suffix, - path_set const & files, - path_set const & excluded) +inventory_paths(inventory_map & inventory, + path_set const & paths, + inventory_item::pstat path_status, + inventory_item::ptype path_type = inventory_item::FILE) { - for (path_set::const_iterator i = files.begin(); i != files.end(); ++i) + for (path_set::const_iterator i = paths.begin(); i != paths.end(); i++) { - if (excluded.find(*i) == excluded.end()) - cout << status << " " << basic_io::escape((*i)() + suffix) << endl; + L(F("%d %d %s\n") % inventory[*i].path_status % path_status % *i); + I(inventory[*i].path_status == inventory_item::UNCHANGED_PATH); + inventory[*i].path_status = path_status; + inventory[*i].path_type = path_type; } } static void -print_inventory(std::string const & status, - std::string const & suffix, - std::map const & renames, - path_set const & excluded) - +inventory_paths(inventory_map & inventory, + path_set const & paths, + inventory_item::dstat data_status) { - for (std::map::const_iterator i = renames.begin(); - i != renames.end(); ++i) + for (path_set::const_iterator i = paths.begin(); i != paths.end(); i++) { - if (excluded.find(i->second) == excluded.end()) - cout << status - << " " << basic_io::escape(i->first() + suffix) - << " " << basic_io::escape(i->second() + suffix) - << endl; + L(F("%d %d %s\n") % inventory[*i].data_status % data_status % *i); + I(inventory[*i].data_status == inventory_item::UNCHANGED_DATA); + inventory[*i].data_status = data_status; } } +static void +inventory_paths(inventory_map & inventory, + std::map const & renames, + inventory_item::pstat path_status, + inventory_item::ptype path_type = inventory_item::FILE) +{ + for (std::map::const_iterator i = renames.begin(); + i != renames.end(); i++) + { + L(F("%d %d %s %s\n") % inventory[i->second].path_status % path_status % i->first % i->second); + I(inventory[i->second].path_status == inventory_item::UNCHANGED_PATH); + inventory[i->second].path_status = inventory_item::RENAMED_PATH; + inventory[i->second].path_type = path_type; + inventory[i->second].old_path = i->first; + } +} + CMD(inventory, "informative", "[PATH]...", "inventory of every file in working copy with associated status") { @@ -2149,6 +2180,7 @@ path_set old_paths, new_paths, empty; change_set::path_rearrangement included, excluded; path_set missing, changed, unchanged, unknown, ignored; + inventory_map inventory; app.require_working_copy(); @@ -2160,33 +2192,77 @@ file_itemizer u(app, new_paths, unknown, ignored); walk_tree(u); + // remove deleted paths from the set of unknown paths + + for (path_set::const_iterator i = included.deleted_files.begin(); + i != included.deleted_files.end(); ++i) + unknown.erase(*i); + + for (path_set::const_iterator i = included.deleted_dirs.begin(); + i != included.deleted_dirs.end(); ++i) + unknown.erase(*i); + classify_paths(app, new_paths, m_old, missing, changed, unchanged); - print_inventory("!", "", missing, empty); + inventory_paths(inventory, missing, inventory_item::MISSING_DATA); - // a file may be missing and also added or the target of a rename. or it may - // be added or the target of a rename and also changed. inventory lists each - // file only once with the highest priority status. missing takes precedence - // over added or renamed. added or renamed takes precedence over changed. + inventory_paths(inventory, included.deleted_files, inventory_item::DROPPED_PATH); + inventory_paths(inventory, included.deleted_dirs, inventory_item::DROPPED_PATH, inventory_item::DIRECTORY); - print_inventory("-", "", included.deleted_files, empty); - print_inventory("-", "/", included.deleted_dirs, empty); + inventory_paths(inventory, included.renamed_files, inventory_item::RENAMED_PATH); + inventory_paths(inventory, included.renamed_dirs, inventory_item::RENAMED_PATH, inventory_item::DIRECTORY); - // ensure missing has precedence over renamed - print_inventory("%", "", included.renamed_files, missing); - print_inventory("%", "/", included.renamed_dirs, missing); + inventory_paths(inventory, included.added_files, inventory_item::ADDED_PATH); + inventory_paths(inventory, changed, inventory_item::PATCHED_DATA); - // ensure missing has precedence over added - print_inventory("+", "", included.added_files, missing); - - print_inventory("#", "", changed, empty); + if (app.all_files) + { + inventory_paths(inventory, unchanged, inventory_item::UNCHANGED_DATA); + inventory_paths(inventory, unknown, inventory_item::UNKNOWN_PATH); + inventory_paths(inventory, ignored, inventory_item::IGNORED_PATH); + } - if (app.all_files) + for (inventory_map::const_iterator i = inventory.begin(); i != inventory.end(); ++i) { - print_inventory("=", "", unchanged, empty); - print_inventory("?", "", unknown, empty); - print_inventory("~", "", ignored, empty); + switch (inventory[i->first].path_status) + { + case inventory_item::UNCHANGED_PATH: cout << " "; break; + case inventory_item::ADDED_PATH: cout << "+"; break; + case inventory_item::DROPPED_PATH: cout << "-"; break; + case inventory_item::RENAMED_PATH: cout << "%"; break; + case inventory_item::UNKNOWN_PATH: cout << "?"; break; + case inventory_item::IGNORED_PATH: cout << "~"; break; + } + + switch (inventory[i->first].data_status) + { + case inventory_item::UNCHANGED_DATA: cout << " "; break; + case inventory_item::PATCHED_DATA: cout << "#"; break; + case inventory_item::MISSING_DATA: cout << "!"; break; + } + + cout << " "; + + switch (inventory[i->first].path_type) + { + case inventory_item::FILE: + if (inventory[i->first].path_status == inventory_item::RENAMED_PATH) + cout << basic_io::escape(inventory[i->first].old_path()) << " "; + + cout << basic_io::escape(i->first()); + break; + + case inventory_item::DIRECTORY: + if (inventory[i->first].path_status == inventory_item::RENAMED_PATH) + cout << basic_io::escape(inventory[i->first].old_path() + "/") << " "; + + cout << basic_io::escape(i->first() + "/"); + break; + } + + cout << endl; } + } CMD(list, "informative", --- monotone.texi +++ monotone.texi @@ -3627,19 +3627,26 @@ @itemx monotone inventory @var{pathname...} This command prints the ``inventory'' of files in a working copy. Each -file is prefixed by a single character indicating the status of the -associated file. +file is prefixed by two characters indicating the current status of the +file's path and associated data or contents. + +The first status character may be one of the following: @itemize address@hidden ! missing file address@hidden - dropped file address@hidden % renamed file address@hidden + added file address@hidden # changed file address@hidden = unchanged file address@hidden ? unknown file address@hidden ~ ignored file address@hidden ' ' the path is unchanged from the current manifest address@hidden '+' the path has been added to the current manifest address@hidden '-' the path has been dropped from the current manifest address@hidden '%' the path has been renamed in the current manifest, both the old and new name are listed address@hidden '?' the path is unknown, it exists in the working copy but not in the current manifest address@hidden '~' the path is ignored by the current ignore_file lua hook setting @end itemize +The second status character may be one of the following: address@hidden address@hidden ' ' the data is unchanged, its sha1 version matches the version in the base manifest address@hidden '#' the data is changed, its sha1 version differs from the version in the base manifest address@hidden '!' the data is missing and its sha1 version cannot be computed address@hidden itemize + By default the @command{inventory} command lists only ``interesting'' files, considered to be those with a status of missing, dropped, renamed, added or changed. If the @option{--all-files} option is @@ -3664,20 +3671,13 @@ Renamed files have both the old and new name of the file listed on the same line in the inventory, in that order. -A file may be missing and also added or the target of a rename, or it -may be added or the target of a rename and also changed. The address@hidden command lists each file only once and in these cases -the status with the highest priority will be displayed. The missing -status takes precedence over both added or renamed and these values take -precedence over the changed status. - Since pathnames may contain spaces, quotes and other ``special'' characters, the @command{inventory} command lists quoted filenames to avoid any ambiguities. Full support for versioned directories is not yet complete and the @command{inventory} command will only list entries for renamed or -dropped directories. Directory entries will be designated by pathnames +dropped directories. Directory entries are designated by pathnames ending with the "/" character. @item monotone log --- tests/t_inventory.at +++ tests/t_inventory.at @@ -31,6 +31,7 @@ ]) AT_CHECK(rm missing) + AT_CHECK(mv original renamed) AT_DATA(changed, [something has changed ]) @@ -43,33 +44,33 @@ AT_CHECK(MONOTONE inventory, [], [stdout], [ignore]) -AT_CHECK(grep '^! "missing"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^+ "added"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^- "dropped"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^% "original" "renamed"' stdout, [], [ignore], [ignore]) -#AT_CHECK(grep '^# "changed"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^ ! "missing"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^+ "added"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^- "dropped"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^% "original" "renamed"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^ . "changed"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^= "unchanged"' stdout, [1], [ignore], [ignore]) -AT_CHECK(grep '^? "unknown"' stdout, [1], [ignore], [ignore]) -AT_CHECK(grep '^~ "ignored~"' stdout, [1], [ignore], [ignore]) +AT_CHECK(grep '^ "unchanged"' stdout, [1], [ignore], [ignore]) +AT_CHECK(grep '^? "unknown"' stdout, [1], [ignore], [ignore]) +AT_CHECK(grep '^~ "ignored~"' stdout, [1], [ignore], [ignore]) # with --all-files they're all listed AT_CHECK(MONOTONE inventory --all-files --rcfile inventory_hooks.lua, [], [stdout], [ignore]) -AT_CHECK(grep '^= "unchanged"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^? "unknown"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^~ "ignored~"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^ "unchanged"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^? "unknown"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^~ "ignored~"' stdout, [], [ignore], [ignore]) -# renamed takes precedence over changed +# renamed and changed AT_DATA(renamed, [renamed and changed ]) AT_CHECK(MONOTONE inventory, [], [stdout], [ignore]) -#AT_CHECK(grep '^# "renamed"' stdout, [1], [ignore], [ignore]) -AT_CHECK(grep '^% "original" "renamed"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^%. "renamed"' stdout, [1], [ignore], [ignore]) +AT_CHECK(grep '^% "original" "renamed"' stdout, [], [ignore], [ignore]) # missing renamed and added files @@ -77,17 +78,9 @@ AT_CHECK(MONOTONE inventory, [], [stdout], [ignore]) -AT_CHECK(grep '^! "added"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^! "renamed"' stdout, [], [ignore], [ignore]) -AT_CHECK(grep '^% "original" "renamed"' stdout, [1], [ignore], [ignore]) +AT_CHECK(grep '^+! "added"' stdout, [], [ignore], [ignore]) +AT_CHECK(grep '^%! "original" "renamed"' stdout, [], [ignore], [ignore]) # need tests for deleted and renamed directories, once these actually work! -# check the inventory finds the right number of files - -I_FILES=`MONOTONE inventory --all-files | wc -l` -F_FILES=`find . -type f | wc -l` - -AT_CHECK(test $I_FILES -eq $F_FILES) - AT_CLEANUP