From 3ee81f48e96031f02bc5caab533b0dd1994f9717 Mon Sep 17 00:00:00 2001 From: Enver Haase Date: Mon, 4 May 2020 11:49:02 +0200 Subject: [PATCH] Introduce -protectsametree option useful e.g. if you want to delete duplicates from deviated backup copy from your original tree (where you may want to keep duplicates) in order to let only the deviated / added files survive. --- Rdutil.cc | 21 ++++++++++++--------- Rdutil.hh | 5 +++-- rdfind.cc | 7 ++++++- 3 files changed, 21 insertions(+), 12 deletions(-) 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);