From: Arvin Schnell Date: Thu, 11 Aug 2011 10:10:50 +0000 (+0200) Subject: - improvements to command-line interface X-Git-Tag: v0.1.3~304 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a0be6b9494aced6d26476940f53818f37231e22b;p=thirdparty%2Fsnapper.git - improvements to command-line interface --- diff --git a/LIBVERSION b/LIBVERSION index 26aaba0e..f0bb29e7 100644 --- a/LIBVERSION +++ b/LIBVERSION @@ -1 +1 @@ -1.2.0 +1.3.0 diff --git a/doc/snapper.8.in b/doc/snapper.8.in index b59cfd28..cc28afea 100644 --- a/doc/snapper.8.in +++ b/doc/snapper.8.in @@ -13,7 +13,7 @@ snapper \fBhelp\fR .SH "DESCRIPTION" .LP Snapper is a command\-line program for filesystem snapshot management. It can -create, delete and compare snapshots and rollback changes between +create, delete and compare snapshots and undo changes between snapshots. Supported filesystems are btrfs and ext4. .SH CONCEPTS @@ -156,23 +156,26 @@ Mount a snapshot. Not required for all filesystem types. Unmount a snapshot. Not required for all filesystem types. .TP -.B diff [options] +.B diff [options] .. Compare the snapshots number1 and number2. This will show a list of files and directories that have been created, modified or deleted in the time between the two snapshots have been made. .TP \fI\-o, \-\-output\fR Write output to file . + .TP -\fI\-f, \-\-file\fR -Compare the file between the two snapshots. +.B contentdiff [options] .. [files] +Compare the snapshots number1 and number2. This will show a diff of the +content of files and directories that have been created, modified or deleted +in the time between the two snapshots have been made. .TP -.B rollback [options] -Rollback changes done between snapshot number1 and number2. +.B undochange [options] .. [files] +Undo changes done between snapshot number1 and number2. .TP -\fI\-f, \-\-file\fR -Read the files to rollback from the file . +\fI\-i, \-\-input\fR +Read files for which to undo changes from file . .TP .B cleanup diff --git a/package/snapper.changes b/package/snapper.changes index 03b48191..67a8a5b6 100644 --- a/package/snapper.changes +++ b/package/snapper.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Thu Aug 11 12:09:19 CEST 2011 - aschnell@suse.de + +- improvements to command-line interface + ------------------------------------------------------------------- Thu Aug 04 20:51:59 CEST 2011 - aschnell@suse.de diff --git a/snapper/Comparison.cc b/snapper/Comparison.cc index a19e79c3..05c80272 100644 --- a/snapper/Comparison.cc +++ b/snapper/Comparison.cc @@ -36,7 +36,7 @@ namespace snapper { if (snapshot1 == snapper->getSnapshots().end() || snapshot2 == snapper->getSnapshots().end() || - snapshot1 == snapshot2) + snapshot1 == snapshot2 || snapshot1->isCurrent()) throw IllegalSnapshotException(); y2mil("num1:" << snapshot1->getNum() << " num2:" << snapshot2->getNum()); @@ -45,17 +45,17 @@ namespace snapper } - RollbackStatistic - Comparison::getRollbackStatistic() const + UndoStatistic + Comparison::getUndoStatistic() const { - return files.getRollbackStatistic(); + return files.getUndoStatistic(); } bool - Comparison::doRollback() + Comparison::doUndo() { - return files.doRollback(); + return files.doUndo(); } } diff --git a/snapper/Comparison.h b/snapper/Comparison.h index 95ffaa8e..8a677a71 100644 --- a/snapper/Comparison.h +++ b/snapper/Comparison.h @@ -47,9 +47,9 @@ namespace snapper Files& getFiles() { return files; } const Files& getFiles() const { return files; } - RollbackStatistic getRollbackStatistic() const; + UndoStatistic getUndoStatistic() const; - bool doRollback(); + bool doUndo(); private: diff --git a/snapper/File.cc b/snapper/File.cc index bdf295a8..aacef6da 100644 --- a/snapper/File.cc +++ b/snapper/File.cc @@ -45,7 +45,7 @@ namespace snapper { - std::ostream& operator<<(std::ostream& s, const RollbackStatistic& rs) + std::ostream& operator<<(std::ostream& s, const UndoStatistic& rs) { s << "numCreate:" << rs.numCreate << " numModify:" << rs.numModify @@ -55,14 +55,14 @@ namespace snapper } - RollbackStatistic::RollbackStatistic() + UndoStatistic::UndoStatistic() : numCreate(0), numModify(0), numDelete(0) { } bool - RollbackStatistic::empty() const + UndoStatistic::empty() const { return numCreate == 0 && numModify == 0 && numDelete == 0; } @@ -641,15 +641,15 @@ namespace snapper bool - File::doRollback() + File::doUndo() { - if (getSnapper()->getRollbackCallback()) + if (getSnapper()->getUndoCallback()) { switch (getAction()) { - case CREATE: getSnapper()->getRollbackCallback()->createInfo(name); break; - case MODIFY: getSnapper()->getRollbackCallback()->modifyInfo(name); break; - case DELETE: getSnapper()->getRollbackCallback()->deleteInfo(name); break; + case CREATE: getSnapper()->getUndoCallback()->createInfo(name); break; + case MODIFY: getSnapper()->getUndoCallback()->modifyInfo(name); break; + case DELETE: getSnapper()->getUndoCallback()->deleteInfo(name); break; } } @@ -673,13 +673,13 @@ namespace snapper error = true; } - if (error && getSnapper()->getRollbackCallback()) + if (error && getSnapper()->getUndoCallback()) { switch (getAction()) { - case CREATE: getSnapper()->getRollbackCallback()->createError(name); break; - case MODIFY: getSnapper()->getRollbackCallback()->modifyError(name); break; - case DELETE: getSnapper()->getRollbackCallback()->deleteError(name); break; + case CREATE: getSnapper()->getUndoCallback()->createError(name); break; + case MODIFY: getSnapper()->getUndoCallback()->modifyError(name); break; + case DELETE: getSnapper()->getUndoCallback()->deleteError(name); break; } } @@ -698,14 +698,14 @@ namespace snapper } - RollbackStatistic - Files::getRollbackStatistic() const + UndoStatistic + Files::getUndoStatistic() const { - RollbackStatistic rs; + UndoStatistic rs; for (vector::const_iterator it = entries.begin(); it != entries.end(); ++it) { - if (it->getRollback()) + if (it->getUndo()) { switch (it->getAction()) { @@ -721,39 +721,39 @@ namespace snapper bool - Files::doRollback() + Files::doUndo() { - y2mil("begin rollback"); + y2mil("begin doUndo"); - if (getSnapper()->getRollbackCallback()) - getSnapper()->getRollbackCallback()->start(); + if (getSnapper()->getUndoCallback()) + getSnapper()->getUndoCallback()->start(); for (vector::reverse_iterator it = entries.rbegin(); it != entries.rend(); ++it) { - if (it->getRollback()) + if (it->getUndo()) { if (it->getPreToPostStatus() == CREATED) { - it->doRollback(); + it->doUndo(); } } } for (vector::iterator it = entries.begin(); it != entries.end(); ++it) { - if (it->getRollback()) + if (it->getUndo()) { if (it->getPreToPostStatus() != CREATED) { - it->doRollback(); + it->doUndo(); } } } - if (getSnapper()->getRollbackCallback()) - getSnapper()->getRollbackCallback()->stop(); + if (getSnapper()->getUndoCallback()) + getSnapper()->getUndoCallback()->stop(); - y2mil("end rollback"); + y2mil("end doUndo"); return true; } diff --git a/snapper/File.h b/snapper/File.h index ce37c6e6..503ebfc3 100644 --- a/snapper/File.h +++ b/snapper/File.h @@ -57,9 +57,9 @@ namespace snapper }; - struct RollbackStatistic + struct UndoStatistic { - RollbackStatistic(); + UndoStatistic(); bool empty() const; @@ -67,7 +67,7 @@ namespace snapper unsigned int numModify; unsigned int numDelete; - friend std::ostream& operator<<(std::ostream& s, const RollbackStatistic& rs); + friend std::ostream& operator<<(std::ostream& s, const UndoStatistic& rs); }; @@ -78,7 +78,7 @@ namespace snapper File(const Comparison* comparison, const string& name, unsigned int pre_to_post_status) : comparison(comparison), name(name), pre_to_post_status(pre_to_post_status), - pre_to_system_status(-1), post_to_system_status(-1), rollback(false) + pre_to_system_status(-1), post_to_system_status(-1), undo(false) {} const string& getName() const { return name; } @@ -93,10 +93,12 @@ namespace snapper vector getDiff(const string& options) const; - bool getRollback() const { return rollback; } - void setRollback(bool value) { rollback = value; } + bool getUndo() const { return undo; } + void setUndo(bool value) { undo = value; } + bool doUndo(); - bool doRollback(); + void setRollback(bool value) __attribute__ ((deprecated)) { setUndo(value); } + bool doRollback() __attribute__ ((deprecated)) { return doUndo(); } enum Action { CREATE, MODIFY, DELETE }; @@ -127,7 +129,7 @@ namespace snapper unsigned int pre_to_system_status; // -1 if invalid unsigned int post_to_system_status; // -1 if invalid - bool rollback; + bool undo; }; @@ -175,9 +177,9 @@ namespace snapper bool save(); void filter(); - RollbackStatistic getRollbackStatistic() const; + UndoStatistic getUndoStatistic() const; - bool doRollback(); + bool doUndo(); const Comparison* comparison; diff --git a/snapper/Snapper.cc b/snapper/Snapper.cc index 6b97757f..02562859 100644 --- a/snapper/Snapper.cc +++ b/snapper/Snapper.cc @@ -48,7 +48,7 @@ namespace snapper Snapper::Snapper(const string& config_name, bool disable_filters) : config_name(config_name), config(NULL), subvolume("/"), filesystem(NULL), - snapshots(this), compare_callback(NULL), rollback_callback(NULL) + snapshots(this), compare_callback(NULL), undo_callback(NULL) { y2mil("Snapper constructor"); y2mil("libsnapper version " VERSION); diff --git a/snapper/Snapper.h b/snapper/Snapper.h index 90a6f635..6ed9a080 100644 --- a/snapper/Snapper.h +++ b/snapper/Snapper.h @@ -48,10 +48,10 @@ namespace snapper }; - struct RollbackCallback + struct UndoCallback { - RollbackCallback() {} - virtual ~RollbackCallback() {} + UndoCallback() {} + virtual ~UndoCallback() {} virtual void start() = 0; virtual void stop() = 0; @@ -133,8 +133,8 @@ namespace snapper void setCompareCallback(CompareCallback* p) { compare_callback = p; } CompareCallback* getCompareCallback() const { return compare_callback; } - void setRollbackCallback(RollbackCallback* p) { rollback_callback = p; } - RollbackCallback* getRollbackCallback() const { return rollback_callback; } + void setUndoCallback(UndoCallback* p) { undo_callback = p; } + UndoCallback* getUndoCallback() const { return undo_callback; } const vector& getIgnorePatterns() const { return ignore_patterns; } @@ -166,7 +166,7 @@ namespace snapper Snapshots snapshots; CompareCallback* compare_callback; - RollbackCallback* rollback_callback; + UndoCallback* undo_callback; }; diff --git a/testsuite-real/common.cc b/testsuite-real/common.cc index 6e35ff32..e3da0916 100644 --- a/testsuite-real/common.cc +++ b/testsuite-real/common.cc @@ -40,10 +40,10 @@ struct CompareCallbackImpl : public CompareCallback CompareCallbackImpl compare_callback_impl; -struct RollbackCallbackImpl : public RollbackCallback +struct UndoCallbackImpl : public UndoCallback { - void start() { cout << "running rollback..." << endl; } - void stop() { cout << "rollback done" << endl; } + void start() { cout << "undoing..." << endl; } + void stop() { cout << "undoing done" << endl; } void createInfo(const string& name) { cout << "creating " << name << endl; } void modifyInfo(const string& name) { cout << "modifying " << name << endl; } @@ -54,7 +54,7 @@ struct RollbackCallbackImpl : public RollbackCallback void deleteError(const string& name) { cout << "failed to delete " << name << endl; numDeleteErrors++; } }; -RollbackCallbackImpl rollback_callback_impl; +UndoCallbackImpl undo_callback_impl; void @@ -68,7 +68,7 @@ setup() sh = createSnapper("testsuite"); sh->setCompareCallback(&compare_callback_impl); - sh->setRollbackCallback(&rollback_callback_impl); + sh->setUndoCallback(&undo_callback_impl); } @@ -89,15 +89,15 @@ second_snapshot() void -check_rollback_statistics(unsigned int numCreate, unsigned int numModify, unsigned int numDelete) +check_undo_statistics(unsigned int numCreate, unsigned int numModify, unsigned int numDelete) { Comparison comparison(sh, first, second); Files& files = comparison.getFiles(); for (Files::iterator it = files.begin(); it != files.end(); ++it) - it->setRollback(true); + it->setUndo(true); - RollbackStatistic rs = comparison.getRollbackStatistic(); + UndoStatistic rs = comparison.getUndoStatistic(); check_equal(rs.numCreate, numCreate); check_equal(rs.numModify, numModify); @@ -106,7 +106,7 @@ check_rollback_statistics(unsigned int numCreate, unsigned int numModify, unsign void -rollback() +undo() { numCreateErrors = numModifyErrors = numDeleteErrors = 0; @@ -114,14 +114,14 @@ rollback() Files& files = comparison.getFiles(); for (Files::iterator it = files.begin(); it != files.end(); ++it) - it->setRollback(true); + it->setUndo(true); - comparison.doRollback(); + comparison.doUndo(); } void -check_rollback_errors(unsigned int numCreate, unsigned int numModify, unsigned int numDelete) +check_undo_errors(unsigned int numCreate, unsigned int numModify, unsigned int numDelete) { check_equal(numCreateErrors, numCreate); check_equal(numModifyErrors, numModify); diff --git a/testsuite-real/common.h b/testsuite-real/common.h index 9983ceda..ef01950e 100644 --- a/testsuite-real/common.h +++ b/testsuite-real/common.h @@ -46,11 +46,11 @@ check_failure(const char* str, Type actual, Type expected, const char* file, void setup(); void first_snapshot(); void second_snapshot(); -void check_rollback_statistics(unsigned int numCreate, unsigned int numModify, - unsigned int numDelete); -void rollback(); -void check_rollback_errors(unsigned int numCreate, unsigned int numModify, +void check_undo_statistics(unsigned int numCreate, unsigned int numModify, unsigned int numDelete); +void undo(); +void check_undo_errors(unsigned int numCreate, unsigned int numModify, + unsigned int numDelete); void check_first(); void run_command(const char* command); diff --git a/testsuite-real/directory1.cc b/testsuite-real/directory1.cc index 1275b72d..daf4d0f5 100644 --- a/testsuite-real/directory1.cc +++ b/testsuite-real/directory1.cc @@ -22,11 +22,11 @@ main() run_command("mkdir already-here"); - check_rollback_statistics(1, 0, 0); + check_undo_statistics(1, 0, 0); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/testsuite-real/error1.cc b/testsuite-real/error1.cc index 4a7a4def..adee5366 100644 --- a/testsuite-real/error1.cc +++ b/testsuite-real/error1.cc @@ -20,11 +20,11 @@ main() run_command("touch not-empty/bad"); - check_rollback_statistics(0, 0, 1); + check_undo_statistics(0, 0, 1); - rollback(); + undo(); - check_rollback_errors(0, 0, 1); + check_undo_errors(0, 0, 1); exit(EXIT_SUCCESS); } diff --git a/testsuite-real/error2.cc b/testsuite-real/error2.cc index 4701cdcf..abccbae4 100644 --- a/testsuite-real/error2.cc +++ b/testsuite-real/error2.cc @@ -23,11 +23,11 @@ main() run_command("rm not-here"); - check_rollback_statistics(0, 1, 0); + check_undo_statistics(0, 1, 0); - rollback(); + undo(); - check_rollback_errors(0, 1, 0); + check_undo_errors(0, 1, 0); exit(EXIT_SUCCESS); } diff --git a/testsuite-real/error4.cc b/testsuite-real/error4.cc index 349818e8..cd374c65 100644 --- a/testsuite-real/error4.cc +++ b/testsuite-real/error4.cc @@ -24,11 +24,11 @@ main() run_command("rmdir wrong-type"); run_command("touch wrong-type"); - check_rollback_statistics(1, 0, 0); + check_undo_statistics(1, 0, 0); - rollback(); + undo(); - check_rollback_errors(1, 0, 0); + check_undo_errors(1, 0, 0); exit(EXIT_SUCCESS); } diff --git a/testsuite-real/missing-directory1.cc b/testsuite-real/missing-directory1.cc index d5b0369d..e47c092e 100644 --- a/testsuite-real/missing-directory1.cc +++ b/testsuite-real/missing-directory1.cc @@ -25,11 +25,11 @@ main() run_command("rmdir not-here"); - check_rollback_statistics(2, 0, 0); + check_undo_statistics(2, 0, 0); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/testsuite-real/owner1.cc b/testsuite-real/owner1.cc index fe362ab7..b4475d85 100644 --- a/testsuite-real/owner1.cc +++ b/testsuite-real/owner1.cc @@ -29,11 +29,11 @@ main() second_snapshot(); - check_rollback_statistics(3, 0, 0); + check_undo_statistics(3, 0, 0); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/testsuite-real/owner2.cc b/testsuite-real/owner2.cc index 65b25d2f..9af2b8fc 100644 --- a/testsuite-real/owner2.cc +++ b/testsuite-real/owner2.cc @@ -24,11 +24,11 @@ main() second_snapshot(); - check_rollback_statistics(0, 3, 0); + check_undo_statistics(0, 3, 0); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/testsuite-real/owner3.cc b/testsuite-real/owner3.cc index 1b1c8326..f8dd7328 100644 --- a/testsuite-real/owner3.cc +++ b/testsuite-real/owner3.cc @@ -23,11 +23,11 @@ main() second_snapshot(); - check_rollback_statistics(0, 1, 0); + check_undo_statistics(0, 1, 0); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/testsuite-real/permissions1.cc b/testsuite-real/permissions1.cc index c392dc88..d6cb22a4 100644 --- a/testsuite-real/permissions1.cc +++ b/testsuite-real/permissions1.cc @@ -30,11 +30,11 @@ main() second_snapshot(); - check_rollback_statistics(4, 0, 0); + check_undo_statistics(4, 0, 0); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/testsuite-real/permissions2.cc b/testsuite-real/permissions2.cc index da611249..8232fed3 100644 --- a/testsuite-real/permissions2.cc +++ b/testsuite-real/permissions2.cc @@ -24,11 +24,11 @@ main() second_snapshot(); - check_rollback_statistics(0, 2, 0); + check_undo_statistics(0, 2, 0); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/testsuite-real/simple1.cc b/testsuite-real/simple1.cc index 21abcbf2..2fcbe8e3 100644 --- a/testsuite-real/simple1.cc +++ b/testsuite-real/simple1.cc @@ -28,11 +28,11 @@ main() second_snapshot(); - check_rollback_statistics(3, 0, 3); + check_undo_statistics(3, 0, 3); - rollback(); + undo(); - check_rollback_errors(0, 0, 0); + check_undo_errors(0, 0, 0); check_first(); diff --git a/tools/snapper.cc b/tools/snapper.cc index b790154e..ac4cb815 100644 --- a/tools/snapper.cc +++ b/tools/snapper.cc @@ -194,6 +194,29 @@ readNum(const string& str) } +pair +readNums(const string& str) +{ + string::size_type pos = str.find(".."); + if (pos == string::npos) + { + cerr << _("Invalid snapshots.") << endl; + exit(EXIT_FAILURE); + } + + Snapshots::iterator snap1 = readNum(str.substr(0, pos)); + Snapshots::iterator snap2 = readNum(str.substr(pos + 2)); + + if (snap1 == snap2 || snap1->isCurrent()) + { + cerr << _("Invalid snapshots.") << endl; + exit(EXIT_FAILURE); + } + + return pair(snap1, snap2); +} + + void help_list() { @@ -573,11 +596,10 @@ void help_diff() { cout << _(" Comparing snapshots:") << endl - << _("\tsnapper diff ") << endl + << _("\tsnapper diff ..") << endl << endl << _(" Options for 'diff' command:") << endl << _("\t--output, -o \t\tSave diff to file.") << endl - << _("\t--file, -f \t\tRun diff for file.") << endl << endl; } @@ -587,38 +609,24 @@ command_diff() { const struct option options[] = { { "output", required_argument, 0, 'o' }, - { "file", required_argument, 0, 'f' }, { 0, 0, 0, 0 } }; GetOpts::parsed_opts opts = getopts.parse("diff", options); - if (getopts.numArgs() != 2) + if (getopts.numArgs() != 1) { - cerr << _("Command 'diff' needs two arguments.") << endl; + cerr << _("Command 'diff' needs one argument.") << endl; exit(EXIT_FAILURE); } GetOpts::parsed_opts::const_iterator opt; - Snapshots::const_iterator snap1 = readNum(getopts.popArg()); - Snapshots::const_iterator snap2 = readNum(getopts.popArg()); + pair snaps(readNums(getopts.popArg())); - Comparison comparison(sh, snap1, snap2); + Comparison comparison(sh, snaps.first, snaps.second); const Files& files = comparison.getFiles(); - Files::const_iterator tmp = files.end(); - - if ((opt = opts.find("file")) != opts.end()) - { - tmp = files.findAbsolutePath(opt->second); - if (tmp == files.end()) - { - cerr << sformat(_("File '%s' not included in diff."), opt->second.c_str()) << endl; - exit(EXIT_FAILURE); - } - } - FILE* file = stdout; if ((opt = opts.find("output")) != opts.end()) @@ -631,59 +639,98 @@ command_diff() } } - if (tmp == files.end()) + for (Files::const_iterator it = files.begin(); it != files.end(); ++it) + fprintf(file, "%s %s\n", statusToString(it->getPreToPostStatus()).c_str(), + it->getAbsolutePath(LOC_SYSTEM).c_str()); + + if (file != stdout) + fclose(file); +} + + +void +help_contentdiff() +{ + cout << _(" Comparing snapshots:") << endl + << _("\tsnapper contentdiff .. [files]") << endl + << endl; +} + + +void +command_contentdiff() +{ + GetOpts::parsed_opts opts = getopts.parse("contentdiff", GetOpts::no_options); + + GetOpts::parsed_opts::const_iterator opt; + + pair snaps(readNums(getopts.popArg())); + + Comparison comparison(sh, snaps.first, snaps.second); + + const Files& files = comparison.getFiles(); + + if (getopts.numArgs() == 0) { - for (Files::const_iterator it = files.begin(); it != files.end(); ++it) - fprintf(file, "%s %s\n", statusToString(it->getPreToPostStatus()).c_str(), - it->getAbsolutePath(LOC_SYSTEM).c_str()); + for (Files::const_iterator it1 = files.begin(); it1 != files.end(); ++it1) + { + vector lines = it1->getDiff("--unified --new-file"); + for (vector::const_iterator it2 = lines.begin(); it2 != lines.end(); ++it2) + cout << it2->c_str() << endl; + } } else { - vector lines = tmp->getDiff("--unified --new-file"); - for (vector::const_iterator it = lines.begin(); it != lines.end(); ++it) - fprintf(file, "%s\n", it->c_str()); - } + while (getopts.numArgs() > 0) + { + string name = getopts.popArg(); - if (file != stdout) - fclose(file); + Files::const_iterator tmp = files.findAbsolutePath(name); + if (tmp == files.end()) + continue; + + vector lines = tmp->getDiff("--unified --new-file"); + for (vector::const_iterator it2 = lines.begin(); it2 != lines.end(); ++it2) + cout << it2->c_str() << endl; + } + } } void -help_rollback() +help_undo() { - cout << _(" Rollback snapshots:") << endl - << _("\tsnapper rollback ") << endl + cout << _(" Undo changes:") << endl + << _("\tsnapper undochange .. [files]") << endl << endl - << _(" Options for 'rollback' command:") << endl - << _("\t--file, -f \t\tRead files to rollback from file.") << endl + << _(" Options for 'undochange' command:") << endl + << _("\t--input, -i \t\tRead files for which to undo changes from file.") << endl << endl; } void -command_rollback() +command_undo() { const struct option options[] = { - { "file", required_argument, 0, 'f' }, + { "input", required_argument, 0, 'i' }, { 0, 0, 0, 0 } }; - GetOpts::parsed_opts opts = getopts.parse("rollback", options); - if (getopts.numArgs() != 2) + GetOpts::parsed_opts opts = getopts.parse("undochange", options); + if (getopts.numArgs() < 1) { - cerr << _("Command 'rollback' needs two arguments.") << endl; + cerr << _("Command 'undochange' needs at least one argument.") << endl; exit(EXIT_FAILURE); } - Snapshots::const_iterator snap1 = readNum(getopts.popArg()); - Snapshots::const_iterator snap2 = readNum(getopts.popArg()); + pair snaps(readNums(getopts.popArg())); FILE* file = NULL; GetOpts::parsed_opts::const_iterator opt; - if ((opt = opts.find("file")) != opts.end()) + if ((opt = opts.find("input")) != opts.end()) { file = fopen(opt->second.c_str(), "r"); if (!file) @@ -693,7 +740,7 @@ command_rollback() } } - Comparison comparison(sh, snap1, snap2); + Comparison comparison(sh, snaps.first, snaps.second); Files& files = comparison.getFiles(); @@ -726,16 +773,32 @@ command_rollback() exit(EXIT_FAILURE); } - it->setRollback(true); + it->setUndo(true); } } else { - for (Files::iterator it = files.begin(); it != files.end(); ++it) - it->setRollback(true); + if (getopts.numArgs() == 0) + { + for (Files::iterator it = files.begin(); it != files.end(); ++it) + it->setUndo(true); + } + else + { + while (getopts.numArgs() > 0) + { + string name = getopts.popArg(); + + Files::iterator tmp = files.findAbsolutePath(name); + if (tmp == files.end()) + continue; + + tmp->setUndo(true); + } + } } - RollbackStatistic rs = comparison.getRollbackStatistic(); + UndoStatistic rs = comparison.getUndoStatistic(); if (rs.empty()) { @@ -746,7 +809,7 @@ command_rollback() cout << "create:" << rs.numCreate << " modify:" << rs.numModify << " delete:" << rs.numDelete << endl; - comparison.doRollback(); + comparison.doUndo(); } @@ -826,7 +889,8 @@ command_help() help_mount(); help_umount(); help_diff(); - help_rollback(); + help_contentdiff(); + help_undo(); help_cleanup(); } @@ -840,10 +904,10 @@ struct CompareCallbackImpl : public CompareCallback CompareCallbackImpl compare_callback_impl; -struct RollbackCallbackImpl : public RollbackCallback +struct UndoCallbackImpl : public UndoCallback { - void start() { cout << _("running rollback...") << endl; } - void stop() { cout << _("rollback done") << endl; } + void start() { cout << _("undoing change...") << endl; } + void stop() { cout << _("undoing change done") << endl; } void createInfo(const string& name) { if (verbose) cout << sformat(_("creating %s"), name.c_str()) << endl; } @@ -860,7 +924,7 @@ struct RollbackCallbackImpl : public RollbackCallback { cerr << sformat(_("failed to delete %s"), name.c_str()) << endl; } }; -RollbackCallbackImpl rollback_callback_impl; +UndoCallbackImpl undo_callback_impl; int @@ -879,7 +943,8 @@ main(int argc, char** argv) cmds["mount"] = command_mount; cmds["umount"] = command_umount; cmds["diff"] = command_diff; - cmds["rollback"] = command_rollback; + cmds["contentdiff"] = command_contentdiff; + cmds["undochange"] = command_undo; cmds["cleanup"] = command_cleanup; cmds["help"] = command_help; @@ -970,7 +1035,7 @@ main(int argc, char** argv) if (!quiet) { sh->setCompareCallback(&compare_callback_impl); - sh->setRollbackCallback(&rollback_callback_impl); + sh->setUndoCallback(&undo_callback_impl); } (*cmd->second)();