diff --git a/src/plugins/git/git.pro b/src/plugins/git/git.pro index 4b4bb0bf7ab4b601023e8d67731d93cd54f827b9..f1570b9eab16e6dca8ee9f8b07fe03c4178636d5 100644 --- a/src/plugins/git/git.pro +++ b/src/plugins/git/git.pro @@ -20,7 +20,6 @@ HEADERS += gitplugin.h \ gitsettings.h \ branchdialog.h \ branchmodel.h \ - gitcommand.h \ clonewizard.h \ clonewizardpage.h \ stashdialog.h \ @@ -42,7 +41,6 @@ SOURCES += gitplugin.cpp \ gitsettings.cpp \ branchdialog.cpp \ branchmodel.cpp \ - gitcommand.cpp \ clonewizard.cpp \ clonewizardpage.cpp \ stashdialog.cpp \ diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index bd3cd9d2dfd696b5d1b7a82d168be6ae257a20a1..62b4898f47a77bec88290d1b8d62d8c2fc9be7a0 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -31,7 +31,6 @@ **************************************************************************/ #include "gitclient.h" -#include "gitcommand.h" #include "gitutils.h" #include "commitdata.h" @@ -57,6 +56,7 @@ #include <utils/synchronousprocess.h> #include <utils/environment.h> #include <utils/fileutils.h> +#include <vcsbase/command.h> #include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditorparameterwidget.h> #include <vcsbase/vcsbaseoutputwindow.h> @@ -406,7 +406,7 @@ void GitClient::diff(const QString &workingDirectory, // Create a batch of 2 commands to be run after each other in case // we have a mixture of staged/unstaged files as is the case // when using the submit dialog. - GitCommand *command = createCommand(workingDirectory, editor); + VCSBase::Command *command = createCommand(workingDirectory, editor); // Directory diff? QStringList cmdArgs; @@ -500,7 +500,7 @@ void GitClient::status(const QString &workingDirectory) statusArgs << QLatin1String("-u"); VCSBase::VCSBaseOutputWindow *outwin = outputWindow(); outwin->setRepository(workingDirectory); - GitCommand *command = executeGit(workingDirectory, statusArgs, 0, true); + VCSBase::Command *command = executeGit(workingDirectory, statusArgs, 0, true); connect(command, SIGNAL(finished(bool,int,QVariant)), outwin, SLOT(clearRepository()), Qt::QueuedConnection); } @@ -643,14 +643,14 @@ void GitClient::blame(const QString &workingDirectory, arguments << QLatin1String("--") << fileName; if (!revision.isEmpty()) arguments << revision; - executeGit(workingDirectory, arguments, editor, false, GitCommand::NoReport, lineNumber); + executeGit(workingDirectory, arguments, editor, false, VCSBase::Command::NoReport, lineNumber); } void GitClient::checkoutBranch(const QString &workingDirectory, const QString &branch) { QStringList arguments(QLatin1String("checkout")); arguments << branch; - GitCommand *cmd = executeGit(workingDirectory, arguments, 0, true); + VCSBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); connectRepositoryChanged(workingDirectory, cmd); } @@ -700,7 +700,7 @@ void GitClient::hardReset(const QString &workingDirectory, const QString &commit if (!commit.isEmpty()) arguments << commit; - GitCommand *cmd = executeGit(workingDirectory, arguments, 0, true); + VCSBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); connectRepositoryChanged(workingDirectory, cmd); } @@ -1253,12 +1253,13 @@ bool GitClient::synchronousApplyPatch(const QString &workingDirectory, } // Factory function to create an asynchronous command -GitCommand *GitClient::createCommand(const QString &workingDirectory, - VCSBase::VCSBaseEditorWidget* editor, - bool useOutputToWindow, - int editorLineNumber) +VCSBase::Command *GitClient::createCommand(const QString &workingDirectory, + VCSBase::VCSBaseEditorWidget* editor, + bool useOutputToWindow, + int editorLineNumber) { - GitCommand *command = new GitCommand(gitBinaryPath(), workingDirectory, processEnvironment(), QVariant(editorLineNumber)); + VCSBase::Command *command = new VCSBase::Command(gitBinaryPath(), workingDirectory, processEnvironment()); + command->setCookie(QVariant(editorLineNumber)); if (editor) connect(command, SIGNAL(finished(bool,int,QVariant)), editor, SLOT(commandFinishedGotoLine(bool,int,QVariant))); if (useOutputToWindow) { @@ -1277,16 +1278,16 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory, } // Execute a single command -GitCommand *GitClient::executeGit(const QString &workingDirectory, - const QStringList &arguments, - VCSBase::VCSBaseEditorWidget* editor, - bool useOutputToWindow, - GitCommand::TerminationReportMode tm, - int editorLineNumber, - bool unixTerminalDisabled) +VCSBase::Command *GitClient::executeGit(const QString &workingDirectory, + const QStringList &arguments, + VCSBase::VCSBaseEditorWidget* editor, + bool useOutputToWindow, + VCSBase::Command::TerminationReportMode tm, + int editorLineNumber, + bool unixTerminalDisabled) { outputWindow()->appendCommand(workingDirectory, settings()->stringValue(GitSettings::binaryPathKey), arguments); - GitCommand *command = createCommand(workingDirectory, editor, useOutputToWindow, editorLineNumber); + VCSBase::Command *command = createCommand(workingDirectory, editor, useOutputToWindow, editorLineNumber); command->addJob(arguments, settings()->intValue(GitSettings::timeoutKey)); command->setTerminationReportMode(tm); command->setUnixTerminalDisabled(unixTerminalDisabled); @@ -1415,7 +1416,7 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, if (untracked) statusArgs << QLatin1String("-u"); const bool statusRc = fullySynchronousGit(workingDirectory, statusArgs, &outputText, &errorText); - GitCommand::removeColorCodes(&outputText); + VCSBase::Command::removeColorCodes(&outputText); if (output) *output = commandOutputFromLocal8Bit(outputText); const bool branchKnown = outputText.contains(kBranchIndicatorC); @@ -1941,7 +1942,7 @@ void GitClient::stashPop(const QString &workingDirectory) { QStringList arguments(QLatin1String("stash")); arguments << QLatin1String("pop"); - GitCommand *cmd = executeGit(workingDirectory, arguments, 0, true); + VCSBase::Command *cmd = executeGit(workingDirectory, arguments, 0, true); connectRepositoryChanged(workingDirectory, cmd); } @@ -2140,7 +2141,7 @@ GitSettings *GitClient::settings() const return m_settings; } -void GitClient::connectRepositoryChanged(const QString & repository, GitCommand *cmd) +void GitClient::connectRepositoryChanged(const QString & repository, VCSBase::Command *cmd) { // Bind command success termination with repository to changed signal if (!m_repositoryChangedSignalMapper) { diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 17eb0c657ee0b9bddcaacd9577ec265c8d8c7c76..b5335992e1ab8beec37dca30c2c8e6f8b7aaae3b 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -34,9 +34,9 @@ #define GITCLIENT_H #include "gitsettings.h" -#include "gitcommand.h" #include <coreplugin/editormanager/ieditor.h> +#include <vcsbase/command.h> #include <QtCore/QObject> #include <QtCore/QString> @@ -68,7 +68,6 @@ namespace Internal { class GitPlugin; class GitOutputWindow; -class GitCommand; class CommitData; struct GitSubmitEditorPanelData; class Stash; @@ -245,16 +244,16 @@ private: const QString &dynamicPropertyValue, QWidget *configWidget) const; - GitCommand *createCommand(const QString &workingDirectory, + VCSBase::Command *createCommand(const QString &workingDirectory, VCSBase::VCSBaseEditorWidget* editor = 0, bool useOutputToWindow = false, int editorLineNumber = -1); - GitCommand *executeGit(const QString &workingDirectory, + VCSBase::Command *executeGit(const QString &workingDirectory, const QStringList &arguments, VCSBase::VCSBaseEditorWidget* editor = 0, bool useOutputToWindow = false, - GitCommand::TerminationReportMode tm = GitCommand::NoReport, + VCSBase::Command::TerminationReportMode tm = VCSBase::Command::NoReport, int editorLineNumber = -1, bool unixTerminalDisabled = false); @@ -279,7 +278,7 @@ private: bool *isDirectory, QString *errorMessage, bool revertStaging); - void connectRepositoryChanged(const QString & repository, GitCommand *cmd); + void connectRepositoryChanged(const QString & repository, VCSBase::Command *cmd); bool synchronousPull(const QString &workingDirectory, bool rebase); void syncAbortPullRebase(const QString &workingDir); bool tryLauchingGitK(const QProcessEnvironment &env, diff --git a/src/plugins/git/gitcommand.cpp b/src/plugins/git/gitcommand.cpp deleted file mode 100644 index 0efb2b6f3dff7fd79f287ff60a839d1150d97559..0000000000000000000000000000000000000000 --- a/src/plugins/git/gitcommand.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (info@qt.nokia.com) -** -** -** GNU Lesser General Public License Usage -** -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this file. -** Please review the following information to ensure the GNU Lesser General -** Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** Other Usage -** -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** If you have questions regarding the use of this file, please contact -** Nokia at info@qt.nokia.com. -** -**************************************************************************/ - -#include "gitcommand.h" -#include "gitconstants.h" - -#include <coreplugin/icore.h> -#include <coreplugin/progressmanager/progressmanager.h> -#include <extensionsystem/pluginmanager.h> -#include <utils/synchronousprocess.h> - -#include <QtCore/QDebug> -#include <QtCore/QProcess> -#include <QtCore/QFuture> -#include <QtCore/QtConcurrentRun> -#include <QtCore/QFileInfo> -#include <QtCore/QCoreApplication> - -Q_DECLARE_METATYPE(QVariant) - -namespace Git { -namespace Internal { - -static QString msgTermination(int exitCode, const QString &binaryPath, const QStringList &args) -{ - QString cmd = QFileInfo(binaryPath).baseName(); - if (!args.empty()) { - cmd += QLatin1Char(' '); - cmd += args.front(); - } - return exitCode ? - QCoreApplication::translate("GitCommand", "\n'%1' failed (exit code %2).\n").arg(cmd).arg(exitCode) : - QCoreApplication::translate("GitCommand", "\n'%1' completed (exit code %2).\n").arg(cmd).arg(exitCode); -} - -GitCommand::Job::Job(const QStringList &a, int t) : - arguments(a), - timeout(t) -{ - // Finished cookie is emitted via queued slot, needs metatype - static const int qvMetaId = qRegisterMetaType<QVariant>(); - Q_UNUSED(qvMetaId) -} - -GitCommand::GitCommand(const QString &binary, - const QString &workingDirectory, - const QProcessEnvironment&environment, - const QVariant &cookie) : - m_binaryPath(binary), - m_workingDirectory(workingDirectory), - m_environment(environment), - m_cookie(cookie), - m_unixTerminalDisabled(false), - m_reportTerminationMode(NoReport) -{ -} - -GitCommand::TerminationReportMode GitCommand::reportTerminationMode() const -{ - return m_reportTerminationMode; -} - -void GitCommand::setTerminationReportMode(TerminationReportMode m) -{ - m_reportTerminationMode = m; -} - -bool GitCommand::unixTerminalDisabled() const -{ - return m_unixTerminalDisabled; -} - -void GitCommand::setUnixTerminalDisabled(bool e) -{ - m_unixTerminalDisabled = e; -} - -void GitCommand::addJob(const QStringList &arguments, int timeout) -{ - m_jobs.push_back(Job(arguments, timeout)); -} - -void GitCommand::execute() -{ - if (m_jobs.empty()) - return; - - // For some reason QtConcurrent::run() only works on this - QFuture<void> task = QtConcurrent::run(this, &GitCommand::run); - const QString taskName = QLatin1String("Git ") + m_jobs.front().arguments.at(0); - - Core::ICore::instance()->progressManager()->addTask(task, taskName, - QLatin1String("Git.action")); -} - -void GitCommand::run() -{ - const unsigned processFlags = m_unixTerminalDisabled ? - unsigned(Utils::SynchronousProcess::UnixTerminalDisabled) : - unsigned(0); - const QSharedPointer<QProcess> process = - Utils::SynchronousProcess::createProcess(processFlags); - if (!m_workingDirectory.isEmpty()) - process->setWorkingDirectory(m_workingDirectory); - - process->setProcessEnvironment(m_environment); - - QByteArray stdOut; - QByteArray stdErr; - QString error; - - const int count = m_jobs.size(); - int exitCode = -1; - bool ok = true; - for (int j = 0; j < count; j++) { - process->start(m_binaryPath, m_jobs.at(j).arguments); - if (!process->waitForStarted()) { - ok = false; - error += QString::fromLatin1("Error: \"%1\" could not be started: %2").arg(m_binaryPath, process->errorString()); - break; - } - - process->closeWriteChannel(); - const int timeOutSeconds = m_jobs.at(j).timeout; - if (!Utils::SynchronousProcess::readDataFromProcess(*process, timeOutSeconds * 1000, - &stdOut, &stdErr, false)) { - Utils::SynchronousProcess::stopProcess(*process); - ok = false; - error += tr("Error: Git timed out after %1s.").arg(timeOutSeconds); - break; - } - - error += QString::fromLocal8Bit(stdErr); - exitCode = process->exitCode(); - switch (m_reportTerminationMode) { - case NoReport: - break; - case ReportStdout: - stdOut += msgTermination(exitCode, m_binaryPath, m_jobs.at(j).arguments).toUtf8(); - break; - case ReportStderr: - error += msgTermination(exitCode, m_binaryPath, m_jobs.at(j).arguments); - break; - } - } - - // Special hack: Always produce output for diff - if (ok && stdOut.isEmpty() && m_jobs.front().arguments.at(0) == QLatin1String("diff")) { - stdOut += "No difference to HEAD"; - } else { - // @TODO: Remove, see below - if (ok && m_jobs.front().arguments.at(0) == QLatin1String("status")) - removeColorCodes(&stdOut); - } - - if (ok && !stdOut.isEmpty()) - emit outputData(stdOut); - - if (!error.isEmpty()) - emit errorText(error); - - emit finished(ok, exitCode, m_cookie); - if (ok) - emit success(); - // As it is used asynchronously, we need to delete ourselves - this->deleteLater(); -} - -// Clean output from carriage return and ANSI color codes. -// @TODO: Remove once all relevant commands support "--no-color", -//("status" is missing it as of git 1.6.2) - -void GitCommand::removeColorCodes(QByteArray *data) -{ - // Remove ansi color codes that look like "ESC[<stuff>m" - const QByteArray ansiColorEscape("\033["); - int escapePos = 0; - while (true) { - const int nextEscapePos = data->indexOf(ansiColorEscape, escapePos); - if (nextEscapePos == -1) - break; - const int endEscapePos = data->indexOf('m', nextEscapePos + ansiColorEscape.size()); - if (endEscapePos != -1) { - data->remove(nextEscapePos, endEscapePos - nextEscapePos + 1); - escapePos = nextEscapePos; - } else { - escapePos = nextEscapePos + ansiColorEscape.size(); - } - } -} - -void GitCommand::setCookie(const QVariant &cookie) -{ - m_cookie = cookie; -} - -QVariant GitCommand::cookie() const -{ - return m_cookie; -} - -} // namespace Internal -} // namespace Git diff --git a/src/plugins/git/gitcommand.h b/src/plugins/git/gitcommand.h deleted file mode 100644 index b31acc1436ee76ac4ae4f2d552c99259070e1e0a..0000000000000000000000000000000000000000 --- a/src/plugins/git/gitcommand.h +++ /dev/null @@ -1,108 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (info@qt.nokia.com) -** -** -** GNU Lesser General Public License Usage -** -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this file. -** Please review the following information to ensure the GNU Lesser General -** Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** Other Usage -** -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** If you have questions regarding the use of this file, please contact -** Nokia at info@qt.nokia.com. -** -**************************************************************************/ - -#ifndef GITCOMMAND_H -#define GITCOMMAND_H - -#include <QtCore/QObject> -#include <QtCore/QStringList> -#include <QtCore/QVariant> -#include <QtCore/QProcessEnvironment> - -namespace Git { -namespace Internal { - -// Asynchronous command with output signals and a finished -// signal with a magic cookie -class GitCommand : public QObject -{ - Q_OBJECT - -public: - // Where to report command termination with exit code if desired - enum TerminationReportMode { NoReport, - ReportStdout, // This assumes UTF8 - ReportStderr }; - - GitCommand(const QString &binary, - const QString &workingDirectory, - const QProcessEnvironment &environment, - const QVariant &cookie = QVariant()); - - void addJob(const QStringList &arguments, int timeout); - void execute(); - - // Clean output from carriage return and ANSI color codes. - // Workaround until all relevant commands support "--no-color". - static void removeColorCodes(QByteArray *data); - - // Report command termination with exit code - TerminationReportMode reportTerminationMode() const; - void setTerminationReportMode(TerminationReportMode m); - - // Disable Terminal on UNIX (see VCS SSH handling). - bool unixTerminalDisabled() const; - void setUnixTerminalDisabled(bool); - - void setCookie(const QVariant &cookie); - QVariant cookie() const; - -private: - void run(); - -signals: - void outputData(const QByteArray &); - void errorText(const QString &); - void finished(bool ok, int exitCode, const QVariant &cookie); - void success(); - -private: - struct Job { - explicit Job(const QStringList &a, int t); - - QStringList arguments; - int timeout; - }; - - const QString m_binaryPath; - const QString m_workingDirectory; - const QProcessEnvironment m_environment; - QVariant m_cookie; - bool m_unixTerminalDisabled; - - QList<Job> m_jobs; - TerminationReportMode m_reportTerminationMode; -}; - -} // namespace Internal -} // namespace Git -#endif // GITCOMMAND_H