# # # patch "ChangeLog" # from [20eab179209dd84a6ffbe774abf064cf7eac7587] # to [6df53a0d0d9127f67e15f0244b2bc7fc8d00f126] # # patch "app_state.cc" # from [2231196507c7aae17ee5955c5a0a623e835c2387] # to [5125b76d02163ea813bd054a4b6e2c0b17942cf6] # # patch "app_state.hh" # from [6afa53915b8c15e9e07b6380e45f30397ec918b9] # to [d4a3ea9c7d8f40ea415be31b7019a521b54e7ef9] # # patch "commands.cc" # from [5d5b0a3a1addff3594125d77ddca94a26ac8d3c3] # to [8ad0bd06efcc5111af0f374f0832dcfdf2fca237] # # patch "monotone.cc" # from [a7917f741c175240312a0c3f1bb9b7a009affe78] # to [9b11ba942536171d28183446bb2fb30338c2a2ee] # # patch "options.hh" # from [216cb82f6f82b63b0f1535b39bb985a237b43359] # to [db7002b03fc93c0456a360c5cc212c6b796950c9] # # patch "tests/t_add_intermediate_MT_path.at" # from [4c5f65b5f92f5b3c897b694de2179138826f5b8c] # to [2f59bba6a5f0be5473ab14fd45ece15679b49fe0] # # patch "tests/t_delete_dir.at" # from [d16637f75dc02d3532ee1a9ebf1071a7a82e2ec0] # to [103572849dde2aaa5352a7397f0626df10270f34] # # patch "tests/t_delete_dir_patch.at" # from [8ee0b4ec75cbe5373ee6a6b592e4ebd60fe38cc5] # to [c5e0a8c0919eb30be885c086894ea908cf0a99ce] # # patch "tests/t_subdir_drop.at" # from [cbf86582b2bd6db9f1fc699e8b97aacbaf472a93] # to [96d6401411920ea2e1a6ac380f662699b8362c22] # # patch "work.cc" # from [5a1ae550863011a4dba19abc3f1fba84d5324a1d] # to [9565a4f3a4d42272f74f916621236d9c354063b2] # ============================================================ --- ChangeLog 20eab179209dd84a6ffbe774abf064cf7eac7587 +++ ChangeLog 6df53a0d0d9127f67e15f0244b2bc7fc8d00f126 @@ -1,3 +1,12 @@ +2006-03-06 Timothy Brownawell + + * app_state.{cc,hh}, options.hh, monotone.cc: Add a --recursive option. + * commands.cc (drop): accept --recursive + * work.cc (perform_deletions): obey --recursive + * tests/t_delete_dir{,_patch}.at, tests/t_subdir_drop.at: + use --recursive, remove XFAIL + * tests/t_add_intermediate_MT_path.at: reenable recursive drop section + 2006-03-05 Timothy Brownawell * commands.cc (db set_epoch): N() on the epoch size, so we don't I() ============================================================ --- app_state.cc 2231196507c7aae17ee5955c5a0a623e835c2387 +++ app_state.cc 5125b76d02163ea813bd054a4b6e2c0b17942cf6 @@ -29,8 +29,8 @@ static string const keydir_option("keydir"); app_state::app_state() - : branch_name(""), db(system_path()), keys(this), stdhooks(true), - rcfiles(true), diffs(false), + : branch_name(""), db(system_path()), keys(this), recursive(false), + stdhooks(true), rcfiles(true), diffs(false), no_merges(false), set_default(false), verbose(false), date_set(false), search_root("/"), depth(-1), last(-1), next(-1), diff_format(unified_diff), diff_args_provided(false), @@ -458,6 +458,12 @@ } void +app_state::set_recursive(bool r) +{ + recursive = r; +} + +void app_state::add_rcfile(utf8 const & filename) { extra_rcfiles.push_back(filename); ============================================================ --- app_state.hh 6afa53915b8c15e9e07b6380e45f30397ec918b9 +++ app_state.hh d4a3ea9c7d8f40ea415be31b7019a521b54e7ef9 @@ -37,6 +37,7 @@ database db; lua_hooks lua; key_store keys; + bool recursive; bool stdhooks; bool rcfiles; bool diffs; @@ -124,6 +125,7 @@ void set_diff_format(diff_type dtype); void set_diff_args(utf8 const & args); void add_key_to_push(utf8 const & key); + void set_recursive(bool r = true); void set_stdhooks(bool b); void set_rcfiles(bool b); ============================================================ --- commands.cc 5d5b0a3a1addff3594125d77ddca94a26ac8d3c3 +++ commands.cc 8ad0bd06efcc5111af0f374f0832dcfdf2fca237 @@ -1216,7 +1216,7 @@ vector const & args, path_set & missing); CMD(drop, N_("workspace"), N_("[PATH]..."), - N_("drop files from workspace"), OPT_EXECUTE % OPT_MISSING) + N_("drop files from workspace"), OPT_EXECUTE % OPT_MISSING % OPT_RECURSIVE) { if (!app.missing && (args.size() < 1)) throw usage(name); ============================================================ --- monotone.cc a7917f741c175240312a0c3f1bb9b7a009affe78 +++ monotone.cc 9b11ba942536171d28183446bb2fb30338c2a2ee @@ -75,6 +75,7 @@ {"key-to-push", 0, POPT_ARG_STRING, &argstr, OPT_KEY_TO_PUSH, gettext_noop("push the specified key even if it hasn't signed anything"), NULL}, {"drop-attr", 0, POPT_ARG_STRING, &argstr, OPT_DROP_ATTR, gettext_noop("when rosterifying, drop attrs entries with the given key"), NULL}, {"no-files", 0, POPT_ARG_NONE, NULL, OPT_NO_FILES, gettext_noop("exclude files when printing logs"), NULL}, + {"recursive", 'R', POPT_ARG_NONE, NULL, OPT_RECURSIVE, gettext_noop("also operate on the contents of any listed directories"), NULL}, { NULL, 0, 0, NULL, 0, NULL, NULL } }; @@ -533,6 +534,10 @@ app.no_files = true; break; + case OPT_RECURSIVE: + app.set_recursive(); + break; + case OPT_HELP: default: requested_help = true; ============================================================ --- options.hh 216cb82f6f82b63b0f1535b39bb985a237b43359 +++ options.hh db7002b03fc93c0456a360c5cc212c6b796950c9 @@ -53,3 +53,4 @@ #define OPT_DROP_ATTR 44 #define OPT_NO_FILES 45 #define OPT_LOG 46 +#define OPT_RECURSIVE 47 ============================================================ --- tests/t_add_intermediate_MT_path.at 4c5f65b5f92f5b3c897b694de2179138826f5b8c +++ tests/t_add_intermediate_MT_path.at 2f59bba6a5f0be5473ab14fd45ece15679b49fe0 @@ -60,20 +60,13 @@ # recursive drop -#### FIXME This should be re-enabled when delete_dir works #### -#AT_CHECK(MONOTONE drop dir1, [], [ignore], [ignore]) -# we expect a non-zero exist status here because directory deletion is -# broken once that's fixed this should fail and can be changed to -# expect commit to work +AT_CHECK(MONOTONE drop --recursive dir1, [], [ignore], [ignore]) +COMMIT(testbranch) -#### FIXME ### -#AT_CHECK(MONOTONE commit, [3], [ignore], [ignore]) - AT_CHECK(MONOTONE checkout outdir4, [], [ignore], [ignore]) -# and these will need updating to all be ! -e too -AT_CHECK(test -e outdir4/dir1/MT/testfile1x) +AT_CHECK(test ! -e outdir4/dir1/MT/testfile1x) AT_CHECK(test ! -e outdir4/dir1/MT/testfile2) -AT_CHECK(test -e outdir4/dir1/MT) -AT_CHECK(test -e outdir4/dir1) +AT_CHECK(test ! -e outdir4/dir1/MT) +AT_CHECK(test ! -e outdir4/dir1) AT_CLEANUP ============================================================ --- tests/t_delete_dir.at d16637f75dc02d3532ee1a9ebf1071a7a82e2ec0 +++ tests/t_delete_dir.at 103572849dde2aaa5352a7397f0626df10270f34 @@ -1,29 +1,6 @@ AT_SETUP([(imp) deleting directories]) MONOTONE_SETUP -# This test is a bug report -# TODO: when this is fixed, re-enabled the drop dir part of -# t_add_intermediate_MT_path.at -AT_XFAIL_IF(true) - -# Directory deletion is currently completely broken. - -# Question: what _should_ happen to rename-out here? I have it -# supposed to survive, but I don't think it's actually possible to -# express that with changesets -- we have no way to say "file -# revived", and so we have no way to come up with a changeset from -# $DIR_DELETE_R to the merged revision that preserves rename-out. -# This might be a problem... -# -# I guess that unless we come up with a way to extend the model with -# file-reviving support (which would be useful in and of itself, aside -# from its utility in this case, but would be a significant addition), -# we should declare that implies . - -# After fixing this; t_subdir_drop.at should start passing. -# So should t_delete_dir_patch.at (hopefully). - AT_CHECK(mkdir groundzero) ADD_FILE(groundzero/preexisting, [1 ]) @@ -46,23 +23,35 @@ AT_CHECK(MONOTONE rename rename-in groundzero/rename-in, [], [ignore], [ignore]) AT_CHECK(mv groundzero/rename-out rename-out) AT_CHECK(MONOTONE rename groundzero/rename-out rename-out, [], [ignore], [ignore]) -AT_CHECK(MONOTONE drop groundzero/double-kill, [], [ignore], [ignore]) +AT_CHECK(MONOTONE drop -e groundzero/double-kill, [], [ignore], [ignore]) COMMIT(testbranch) OTHER_OPS_R=`BASE_REVISION` REVERT_TO($BASE_R) -# Boom. -AT_CHECK(MONOTONE drop groundzero, [], [ignore], [ignore]) +# update doesn't remove files... +AT_CHECK(rm groundzero/rename-in) +AT_CHECK(rm groundzero/new-file) + +AT_CHECK(MONOTONE drop --recursive -e groundzero, [], [ignore], [ignore]) COMMIT(testbranch) DIR_DELETE_R=`BASE_REVISION` + +# orphaned node conflicts on rename-in and new-file +AT_CHECK(MONOTONE merge, [1], [ignore], [ignore]) + +AT_CHECK(MONOTONE update -r $OTHER_OPS_R, [], [ignore], [ignore]) +AT_CHECK(MONOTONE drop groundzero/new-file, [], [ignore], [ignore]) +AT_CHECK(MONOTONE drop groundzero/rename-in, [], [ignore], [ignore]) +COMMIT(testbranch) AT_CHECK(MONOTONE merge, [], [ignore], [ignore]) + AT_CHECK(MONOTONE checkout --revision=$BASE_R clean, [], [ignore], [ignore]) AT_CHECK(cd clean && MONOTONE --branch=testbranch update, [], [ignore], [ignore]) -AT_CHECK(test -f clean/rename-out) +AT_CHECK(test -f clean/rename-out, [1]) AT_CHECK(test -f clean/bystander1) AT_CHECK(test -f clean/bystander2) AT_CHECK(test -f clean/groundzero/rename-in, [1]) ============================================================ --- tests/t_delete_dir_patch.at 8ee0b4ec75cbe5373ee6a6b592e4ebd60fe38cc5 +++ tests/t_delete_dir_patch.at c5e0a8c0919eb30be885c086894ea908cf0a99ce @@ -1,11 +1,6 @@ AT_SETUP([(imp) merge(, )]) MONOTONE_SETUP -# This test is a bug report. -AT_XFAIL_IF(true) - -# The problem is the delete_dir is broken generally; see t_delete_dir.at. - AT_CHECK(mkdir foo) ADD_FILE(foo/a, [blah blah ]) @@ -13,7 +8,7 @@ BASE_R=`BASE_REVISION` AT_CHECK(mv foo bar) -AT_CHECK(MONOTONE drop foo, [], [ignore], [ignore]) +AT_CHECK(MONOTONE drop --recursive foo, [], [ignore], [ignore]) COMMIT(testbranch) AT_CHECK(mv bar foo) ============================================================ --- tests/t_subdir_drop.at cbf86582b2bd6db9f1fc699e8b97aacbaf472a93 +++ tests/t_subdir_drop.at 96d6401411920ea2e1a6ac380f662699b8362c22 @@ -1,12 +1,6 @@ AT_SETUP([(minor) drop in subdir]) MONOTONE_SETUP -# This test is a bug report. -AT_XFAIL_IF(true) - -# This test _should_ start working once t_delete_dir.at starts -# working. If not, reinvestigate. - AT_CHECK(mkdir subdir) AT_CHECK(mkdir subdir/anotherdir) AT_DATA(subdir/foo, [data data @@ -21,7 +15,7 @@ AT_CHECK(MONOTONE checkout --revision=$REV codir, [], [ignore], [ignore]) AT_CHECK( (cd subdir && MONOTONE drop foo), [], [ignore], [ignore]) -AT_CHECK( (cd subdir && MONOTONE drop anotherdir), [], [ignore], [ignore]) +AT_CHECK( (cd subdir && MONOTONE drop --recursive anotherdir), [], [ignore], [ignore]) COMMIT(testbranch) AT_CHECK( (cd codir && MONOTONE update), [], [ignore], [ignore]) ============================================================ --- work.cc 5a1ae550863011a4dba19abc3f1fba84d5324a1d +++ work.cc 9565a4f3a4d42272f74f916621236d9c354063b2 @@ -8,6 +8,7 @@ #include #include #include +#include #include "app_state.hh" #include "basic_io.hh" @@ -206,26 +207,49 @@ // where, when processing 'foo', we need to know whether or not it is empty // (and thus legal to remove) - for (path_set::const_reverse_iterator i = paths.rbegin(); i != paths.rend(); ++i) + std::deque todo; + path_set::const_reverse_iterator i = paths.rbegin(); + todo.push_back(*i); + ++i; + + while (todo.size()) { - file_path name(*i); + split_path &p(todo.front()); + file_path name(p); - if (!new_roster.has_node(*i)) + if (!new_roster.has_node(p)) P(F("skipping %s, not currently tracked") % name); else { - node_t n = new_roster.get_node(*i); + node_t n = new_roster.get_node(p); if (is_dir_t(n)) { dir_t d = downcast_to_dir_t(n); - N(d->children.empty(), - F("cannot remove %s/, it is not empty") % name); + if (!d->children.empty()) + { + N(app.recursive, + F("cannot remove %s/, it is not empty") % name); + for (dir_map::const_iterator j = d->children.begin(); + j != d->children.end(); ++j) + { + split_path sp = p; + sp.push_back(j->first); + todo.push_front(sp); + } + continue; + } } P(F("dropping %s from workspace manifest") % name); - new_roster.drop_detached_node(new_roster.detach_node(*i)); + new_roster.drop_detached_node(new_roster.detach_node(p)); if (app.execute && path_exists(name)) delete_file_or_dir_shallow(name); } + todo.pop_front(); + if (i != paths.rend()) + { + todo.push_back(*i); + ++i; + } } cset new_work;