Various fixes for revert/unrevert
[vng.git] / src / commands / UnRevert.cpp
blob0b47be572da109dbe183e56377bc4ae5e0e3defc
1 /*
2 * This file is part of the vng project
3 * Copyright (C) 2008-2009 Thomas Zander <tzander@trolltech.com>
4 * Copyright (C) 2003-2005 David Roundy
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "UnRevert.h"
21 #include "../CommandLineParser.h"
22 #include "Revert.h"
23 #include "../Interview.h"
24 #include "../GitRunner.h"
25 #include "../Logger.h"
26 #include "../hunks/ChangeSet.h"
27 #include "../hunks/HunksCursor.h"
29 #include <QDebug>
31 static const CommandLineOption options[] = {
32 {"-a, --all", "answer yes to all patches"},
33 {"-i, --interactive", "prompt user interactively"},
34 CommandLineLastOption
37 UnRevert::UnRevert()
38 :AbstractCommand("unrevert")
40 CommandLineParser::addOptionDefinitions(options);
43 QString UnRevert::argumentDescription() const
45 return QString();
48 QString UnRevert::commandDescription() const
50 return "Unrevert is used to undo the results of a revert command. It is only\n"
51 "guaranteed to work properly if you haven't made any changes since the\n"
52 "revert was performed.\n";
55 AbstractCommand::ReturnCodes UnRevert::run()
57 if (! checkInRepository())
58 return NotInRepo;
59 moveToRoot();
60 CommandLineParser *args = CommandLineParser::instance();
61 const bool all = (m_config.contains("all") && !args->contains("interactive")) || args->contains("all");
63 ChangeSet changeSet;
64 QFile file(Revert::patchFileName());
65 if (file.exists())
66 changeSet.fillFromDiffFile(file);
68 bool shouldDoRevert = changeSet.count() > 0;
69 if (!shouldDoRevert)
70 Logger::warn() << "There is nothing to unrevert!" << endl;
72 if (shouldDoRevert && !all) { // then do interview
73 HunksCursor cursor(changeSet);
74 Interview interview(cursor, "Shall I unrevert this change?");
75 interview.setUsePager(shouldUsePager());
76 if (! interview.start()) {
77 Logger::warn() << "Unrevert cancelled." << endl;
78 return Ok;
82 if (! dryRun() && shouldDoRevert) { // we then write out the patch and call git apply with it
83 QFile patchFile(Revert::patchFileName() + ".tmp");
84 changeSet.writeDiff(patchFile, all ? ChangeSet::AllHunks : ChangeSet::UserSelection);
85 QProcess git;
86 QStringList arguments;
87 arguments << "apply" << "--apply" << patchFile.fileName();
88 GitRunner runner(git, arguments);
89 AbstractCommand::ReturnCodes rc = runner.start(GitRunner::WaitUntilFinished);
90 //patchFile.remove();
91 if (rc != 0) {
92 Logger::error() << "Unreverting failed on one or more patches";
93 if (Logger::verbosity() < Logger::Chatty)
94 Logger::error() << ", rerun with --standard-verbosity to see the warnings";
95 Logger::error() << endl;
96 Logger::warn() << git.readAllStandardError();
97 Logger::warn().flush();
98 return rc;
100 changeSet.writeDiff(file, all ? ChangeSet::AllHunks : ChangeSet::InvertedUserSelection);
101 if (file.size() == 0)
102 file.remove();
104 arguments.clear();
105 arguments << QLatin1String("update-index") << QLatin1String("--add");
106 for (int i = 0; i < changeSet.count(); ++i) {
107 File file = changeSet.file(i);
108 if ((all || file.renameAcceptance() == Vng::Accepted)
109 && file.oldFileName() != file.fileName()) {
110 if (!file.oldFileName().isEmpty())
111 arguments << file.fileName();
112 } else if (all || file.changesAcceptance() == Vng::Accepted) {
113 arguments << file.fileName();
116 if (arguments.count() > 2) {
117 runner.setArguments(arguments);
118 runner.start(GitRunner::WaitUntilFinished);
121 Logger::warn() << "Finished unreverting." << endl;
122 return Ok;