From 40eecd87c94f7cf8aaaacf636b2efb8238ca4d31 Mon Sep 17 00:00:00 2001
From: Petar Perisin <petar.perisin@gmail.com>
Date: Tue, 8 Jan 2013 00:17:18 +0100
Subject: [PATCH] Git: Refactored "synchronousPullOrRebase" to be more general.

This can ease adding commands that can cause conflicts like cherry-pick,
revert, merge, rebase, stash pop ...

Change-Id: Id9df7f11307dbbcb60036a20a2c22c5097ba239f
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
---
 src/plugins/git/gitclient.cpp | 73 ++++++++++++++++++++++-------------
 src/plugins/git/gitclient.h   |  8 ++--
 src/plugins/git/mergetool.cpp |  2 +-
 3 files changed, 53 insertions(+), 30 deletions(-)

diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 309d89ce685..3b0630df5ec 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -2107,7 +2107,7 @@ bool GitClient::synchronousFetch(const QString &workingDirectory, const QString
     return resp.result == Utils::SynchronousProcessResponse::Finished;
 }
 
-bool GitClient::synchronousMergeOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase)
+bool GitClient::executeAndHandleConflicts(const QString &workingDirectory, const QStringList &arguments, const QString &abortCommand)
 {
     // Disable UNIX terminals to suppress SSH prompting.
     const unsigned flags = VcsBase::VcsBasePlugin::SshPasswordPrompt|VcsBase::VcsBasePlugin::ShowStdOutInLogWindow;
@@ -2117,42 +2117,58 @@ bool GitClient::synchronousMergeOrRebase(const QString &workingDirectory, const
     if (ok)
         GitPlugin::instance()->gitVersionControl()->emitRepositoryChanged(workingDirectory);
     else if (resp.stdOut.contains(QLatin1String("CONFLICT")))
-        handleMergeConflicts(workingDirectory, rebase);
+        handleMergeConflicts(workingDirectory, abortCommand);
     return ok;
 }
 
 bool GitClient::synchronousPull(const QString &workingDirectory, bool rebase)
 {
-    QStringList arguments(QLatin1String("pull"));
-    if (rebase)
+    QString abortCommand;
+    QStringList arguments;
+    if (rebase) {
         arguments << QLatin1String("--rebase");
-    return synchronousMergeOrRebase(workingDirectory, arguments, rebase);
+        abortCommand = QLatin1String("rebase");
+    } else {
+        abortCommand = QLatin1String("merge");
+    }
+
+    return executeAndHandleConflicts(workingDirectory, arguments, abortCommand);
 }
 
-bool GitClient::synchronousRebaseContinue(const QString &workingDirectory)
+bool GitClient::synchronousCommandContinue(const QString &workingDirectory, const QString &command)
 {
-    QStringList arguments(QLatin1String("rebase"));
-    arguments << QLatin1String("--continue");
-    return synchronousMergeOrRebase(workingDirectory, arguments, true);
+    QStringList arguments;
+    arguments << command << QLatin1String("--continue");
+    return executeAndHandleConflicts(workingDirectory, arguments, command);
 }
 
-void GitClient::handleMergeConflicts(const QString &workingDir, bool rebase)
+void GitClient::synchronousAbortCommand(const QString &workingDir, const QString &abortCommand)
+{
+    // Abort to clean if something goes wrong
+    if (abortCommand.isEmpty()) {
+        // no abort command - checkout index to clean working copy.
+        synchronousCheckoutFiles(findRepositoryForDirectory(workingDir), QStringList(), QString(), 0, false);
+        return;
+    }
+    VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance();
+    QStringList arguments;
+    arguments << abortCommand << QLatin1String("--abort");
+    QByteArray stdOut;
+    QByteArray stdErr;
+    const bool rc = fullySynchronousGit(workingDir, arguments, &stdOut, &stdErr, true);
+    outwin->append(commandOutputFromLocal8Bit(stdOut));
+    if (!rc)
+        outwin->appendError(commandOutputFromLocal8Bit(stdErr));
+}
+
+void GitClient::handleMergeConflicts(const QString &workingDir, const QString &abortCommand)
 {
     QMessageBox mergeOrAbort(QMessageBox::Question, tr("Conflicts detected"),
                              tr("Conflicts detected"), QMessageBox::Ignore | QMessageBox::Abort);
     mergeOrAbort.addButton(tr("Run Merge Tool"), QMessageBox::ActionRole);
     switch (mergeOrAbort.exec()) {
     case QMessageBox::Abort: {
-        // Abort merge/rebase to clean if something goes wrong
-        VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance();
-        QStringList arguments;
-        arguments << QLatin1String(rebase ? "rebase" : "merge") << QLatin1String("--abort");
-        QByteArray stdOut;
-        QByteArray stdErr;
-        const bool rc = fullySynchronousGit(workingDir, arguments, &stdOut, &stdErr, true);
-        outwin->append(commandOutputFromLocal8Bit(stdOut));
-        if (!rc)
-            outwin->appendError(commandOutputFromLocal8Bit(stdErr));
+        synchronousAbortCommand(workingDir, abortCommand);
         break;
     }
     case QMessageBox::Ignore:
@@ -2209,19 +2225,24 @@ bool GitClient::synchronousPush(const QString &workingDirectory, const QString &
 
 bool GitClient::synchronousMerge(const QString &workingDirectory, const QString &branch)
 {
-    QStringList arguments(QLatin1String("merge"));
-    arguments << branch;
-    return synchronousMergeOrRebase(workingDirectory, arguments, false);
+    QString command = QLatin1String("merge");
+    QStringList arguments;
+
+    arguments << command << branch;
+    return executeAndHandleConflicts(workingDirectory, arguments, command);
 }
 
 bool GitClient::synchronousRebase(const QString &workingDirectory, const QString &baseBranch,
                                   const QString &topicBranch)
 {
-    QStringList arguments(QLatin1String("rebase"));
-    arguments << baseBranch;
+    QString command = QLatin1String("rebase");
+    QStringList arguments;
+
+    arguments << command << baseBranch;
     if (!topicBranch.isEmpty())
         arguments << topicBranch;
-    return synchronousMergeOrRebase(workingDirectory, arguments, true);
+
+    return executeAndHandleConflicts(workingDirectory, arguments, command);
 }
 
 QString GitClient::msgNoChangedFiles()
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 30860c4bbc2..d7eb76a41fa 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -178,7 +178,7 @@ public:
     QString vcsGetRepositoryURL(const QString &directory);
     bool synchronousFetch(const QString &workingDirectory, const QString &remote);
     bool synchronousPull(const QString &workingDirectory, bool rebase);
-    bool synchronousRebaseContinue(const QString &workingDirectory);
+    bool synchronousCommandContinue(const QString &workingDirectory, const QString &command);
     bool synchronousPush(const QString &workingDirectory, const QString &remote = QString());
     bool synchronousMerge(const QString &workingDirectory, const QString &branch);
     bool synchronousRebase(const QString &workingDirectory,
@@ -301,8 +301,10 @@ private:
                          QString *errorMessage,
                          bool revertStaging);
     void connectRepositoryChanged(const QString & repository, VcsBase::Command *cmd);
-    bool synchronousMergeOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase);
-    void handleMergeConflicts(const QString &workingDir, bool rebase);
+    bool executeAndHandleConflicts(const QString &workingDirectory, const QStringList &arguments,
+                                   const QString &abortCommand = QString());
+    void synchronousAbortCommand(const QString &workingDir, const QString &abortCommand);
+    void handleMergeConflicts(const QString &workingDir, const QString &abortCommand);
     bool tryLauchingGitK(const QProcessEnvironment &env,
                          const QString &workingDirectory,
                          const QString &fileName,
diff --git a/src/plugins/git/mergetool.cpp b/src/plugins/git/mergetool.cpp
index 30401cc0ee7..e9753f8efac 100644
--- a/src/plugins/git/mergetool.cpp
+++ b/src/plugins/git/mergetool.cpp
@@ -267,7 +267,7 @@ void MergeTool::done()
             if (QMessageBox::question(0, tr("Continue Rebase"),
                                       tr("Continue rebase?"),
                                       QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) {
-                client->synchronousRebaseContinue(workingDirectory);
+                client->synchronousCommandContinue(workingDirectory, QLatin1String("rebase"));
             }
         }
     } else {
-- 
GitLab