diff --git a/Rdutil.cc b/Rdutil.cc index f098d2c..6c552f0 100644 --- a/Rdutil.cc +++ b/Rdutil.cc @@ -61,7 +61,7 @@ Rdutil::printtofile(const std::string& filename) const // returns how many times the function was invoked. template std::size_t -applyactiononfile(std::vector& m_list, Function f) +applyactiononfile(std::vector& m_list, bool m_protectSameTree, Function f) { const auto first = m_list.begin(); @@ -79,9 +79,12 @@ applyactiononfile(std::vector& m_list, Function f) "original file should have positive identity"); } break; - case Fileinfo::duptype::DUPTYPE_OUTSIDE_TREE: + case Fileinfo::duptype::DUPTYPE_WITHIN_SAME_TREE: + if (m_protectSameTree) { + break; + } // intentional fallthrough - case Fileinfo::duptype::DUPTYPE_WITHIN_SAME_TREE: { + case Fileinfo::duptype::DUPTYPE_OUTSIDE_TREE: { assert(original != last); // double check that "it" shall be ~linked to "src" assert(it->getidentity() == -original->getidentity() && @@ -140,11 +143,11 @@ Rdutil::deleteduplicates(bool dryrun) const if (dryrun) { const bool outputBname = false; dryrun_helper obj("delete "); - auto ret = applyactiononfile(m_list, obj); + auto ret = applyactiononfile(m_list, m_protectSameTree, obj); std::cout.flush(); return ret; } else { - return applyactiononfile(m_list, &Fileinfo::static_deletefile); + return applyactiononfile(m_list, m_protectSameTree, &Fileinfo::static_deletefile); } } @@ -154,11 +157,11 @@ Rdutil::makesymlinks(bool dryrun) const if (dryrun) { const bool outputBname = true; dryrun_helper obj("symlink ", " to "); - auto ret = applyactiononfile(m_list, obj); + auto ret = applyactiononfile(m_list, m_protectSameTree, obj); std::cout.flush(); return ret; } else { - return applyactiononfile(m_list, &Fileinfo::static_makesymlink); + return applyactiononfile(m_list, m_protectSameTree, &Fileinfo::static_makesymlink); } } @@ -168,11 +171,11 @@ Rdutil::makehardlinks(bool dryrun) const if (dryrun) { const bool outputBname = true; dryrun_helper obj("hardlink ", " to "); - const auto ret = applyactiononfile(m_list, obj); + const auto ret = applyactiononfile(m_list, m_protectSameTree, obj); std::cout.flush(); return ret; } else - return applyactiononfile(m_list, &Fileinfo::static_makehardlink); + return applyactiononfile(m_list, m_protectSameTree, &Fileinfo::static_makehardlink); } // mark files with a unique number diff --git a/Rdutil.hh b/Rdutil.hh index b39e2e9..d4967b6 100644 --- a/Rdutil.hh +++ b/Rdutil.hh @@ -16,8 +16,8 @@ class Rdutil { public: - explicit Rdutil(std::vector& list) - : m_list(list){}; + explicit Rdutil(std::vector& list, bool protectSameTree) + : m_list(list), m_protectSameTree(protectSameTree) {}; /** * print file names to a file, with extra information. @@ -121,6 +121,7 @@ public: private: std::vector& m_list; + bool m_protectSameTree; }; #endif diff --git a/rdfind.cc b/rdfind.cc index facdda7..4c66589 100644 --- a/rdfind.cc +++ b/rdfind.cc @@ -72,6 +72,8 @@ usage() << " -outputname name sets the results file name to \"name\" " "(default results.txt)\n" << " -deleteduplicates true |(false) delete duplicate files\n" + << " -protectsametree true |(false) do not touch duplicates found in " + "the same tree as the original\n" << " -sleep Xms sleep for X milliseconds between " "file reads.\n" << " Default is 0. Only a few values\n" @@ -99,6 +101,7 @@ struct Options Fileinfo::filesizetype maximumfilesize = 0; // if nonzero, files this size or larger are ignored bool deleteduplicates = false; // delete duplicate files + bool protectsametree = false; // do not touch duplicates in same tree bool followsymlinks = false; // follow symlinks bool dryrun = false; // only dryrun, dont destroy anything bool remove_identical_inode = true; // remove files with identical inodes @@ -156,6 +159,8 @@ parseOptions(Parser& parser) o.maximumfilesize = maxsize; } else if (parser.try_parse_bool("-deleteduplicates")) { o.deleteduplicates = parser.get_parsed_bool(); + } else if (parser.try_parse_bool("-protectsametree")) { + o.protectsametree = parser.get_parsed_bool(); } else if (parser.try_parse_bool("-followsymlinks")) { o.followsymlinks = parser.get_parsed_bool(); } else if (parser.try_parse_bool("-dryrun")) { @@ -286,7 +291,7 @@ main(int narg, const char* argv[]) const std::string dryruntext(o.dryrun ? "(DRYRUN MODE) " : ""); // an object to do sorting and duplicate finding - Rdutil gswd(filelist); + Rdutil gswd(filelist, o.protectsametree); // an object to traverse the directory structure Dirlist dirlist(o.followsymlinks);