Fixes: Enable multiselection in file list of git submit editor

Details: Refactor the git command to be able to run a batch. Run diff and diff --cached in a batch
This commit is contained in:
Friedemann Kleint
2009-01-13 17:25:09 +01:00
parent 8dfdfc0600
commit e2ef36a65d
12 changed files with 320 additions and 152 deletions

View File

@@ -32,6 +32,7 @@
***************************************************************************/
#include "gitclient.h"
#include "gitcommand.h"
#include "commitdata.h"
#include "gitconstants.h"
@@ -49,7 +50,6 @@
#include <utils/qtcassert.h>
#include <vcsbase/vcsbaseeditor.h>
#include <QtCore/QFuture>
#include <QtCore/QRegExp>
#include <QtCore/QTemporaryFile>
#include <QtCore/QTime>
@@ -61,7 +61,6 @@
using namespace Git;
using namespace Git::Internal;
const char *const kGitCommand = "git";
const char *const kGitDirectoryC = ".git";
const char *const kBranchIndicatorC = "# On branch";
@@ -186,19 +185,45 @@ VCSBase::VCSBaseEditor
void GitClient::diff(const QString &workingDirectory,
const QStringList &diffArgs,
const QStringList &fileNames)
const QStringList &unstagedFileNames,
const QStringList &stagedFileNames)
{
if (Git::Constants::debug)
qDebug() << "diff" << workingDirectory << fileNames;
QStringList arguments;
arguments << QLatin1String("diff") << diffArgs << QLatin1String("--") << fileNames;
if (Git::Constants::debug)
qDebug() << "diff" << workingDirectory << unstagedFileNames << stagedFileNames;
const QString binary = QLatin1String(Constants::GIT_BINARY);
const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND);
const QString title = tr("Git Diff");
VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, workingDirectory, true, "originalFileName", workingDirectory);
executeGit(workingDirectory, arguments, editor);
// 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);
// Directory diff?
if (unstagedFileNames.empty() && stagedFileNames.empty()) {
QStringList arguments;
arguments << QLatin1String("diff") << diffArgs;
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
command->addJob(arguments);
} else {
// Files diff.
if (!unstagedFileNames.empty()) {
QStringList arguments;
arguments << QLatin1String("diff") << diffArgs << QLatin1String("--") << unstagedFileNames;
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
command->addJob(arguments);
}
if (!stagedFileNames.empty()) {
QStringList arguments;
arguments << QLatin1String("diff") << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames;
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
command->addJob(arguments);
}
}
command->execute();
}
void GitClient::diff(const QString &workingDirectory,
@@ -439,42 +464,47 @@ bool GitClient::synchronousShow(const QString &workingDirectory, const QString &
return true;
}
void GitClient::executeGit(const QString &workingDirectory, const QStringList &arguments,
VCSBase::VCSBaseEditor* editor,
bool outputToWindow)
// Factory function to create an asynchronous command
GitCommand *GitClient::createCommand(const QString &workingDirectory,
VCSBase::VCSBaseEditor* editor,
bool outputToWindow)
{
if (Git::Constants::debug)
qDebug() << "executeGit" << workingDirectory << arguments << editor;
qDebug() << Q_FUNC_INFO << workingDirectory << editor;
GitOutputWindow *outputWindow = m_plugin->outputWindow();
outputWindow->append(formatCommand(QLatin1String(kGitCommand), arguments));
QProcess process;
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
if (m_settings.adoptPath)
environment.set(QLatin1String("PATH"), m_settings.path);
GitCommand* command = new GitCommand();
GitCommand* command = new GitCommand(workingDirectory, environment);
if (outputToWindow) {
if (!editor) { // assume that the commands output is the important thing
connect(command, SIGNAL(outputText(QString)), this, SLOT(appendAndPopup(QString)));
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray)));
} else {
connect(command, SIGNAL(outputText(QString)), outputWindow, SLOT(append(QString)));
connect(command, SIGNAL(outputData(QByteArray)), outputWindow, SLOT(appendData(QByteArray)));
}
} else {
QTC_ASSERT(editor, /**/);
connect(command, SIGNAL(outputText(QString)), editor, SLOT(setPlainText(QString)));
connect(command, SIGNAL(outputData(QByteArray)), editor, SLOT(setPlainTextData(QByteArray)));
}
if (outputWindow)
connect(command, SIGNAL(errorText(QString)), this, SLOT(appendAndPopup(QString)));
return command;
}
command->execute(arguments, workingDirectory, environment);
// Execute a single command
void GitClient::executeGit(const QString &workingDirectory,
const QStringList &arguments,
VCSBase::VCSBaseEditor* editor,
bool outputToWindow)
{
m_plugin->outputWindow()->append(formatCommand(QLatin1String(Constants::GIT_BINARY), arguments));
GitCommand *command = createCommand(workingDirectory, editor, outputToWindow);
command->addJob(arguments);
command->execute();
}
void GitClient::appendDataAndPopup(const QByteArray &data)
@@ -497,7 +527,7 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
{
if (Git::Constants::debug)
qDebug() << "synchronousGit" << workingDirectory << arguments;
const QString binary = QLatin1String(kGitCommand);
const QString binary = QLatin1String(Constants::GIT_BINARY);
if (logCommandToWindow)
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
@@ -973,67 +1003,3 @@ void GitClient::setSettings(const GitSettings &s)
}
}
// ------------------------ GitCommand
GitCommand::GitCommand()
{
}
GitCommand::~GitCommand()
{
}
void GitCommand::execute(const QStringList &arguments,
const QString &workingDirectory,
const ProjectExplorer::Environment &environment)
{
if (Git::Constants::debug)
qDebug() << "GitCommand::execute" << workingDirectory << arguments;
// For some reason QtConcurrent::run() only works on this
QFuture<void> task = QtConcurrent::run(this, &GitCommand::run
, arguments
, workingDirectory
, environment);
QString taskName = QLatin1String("Git ") + arguments[0];
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
core->progressManager()->addTask(task, taskName
, QLatin1String("Git.action")
, Core::ProgressManager::CloseOnSuccess);
}
void GitCommand::run(const QStringList &arguments,
const QString &workingDirectory,
const ProjectExplorer::Environment &environment)
{
if (Git::Constants::debug)
qDebug() << "GitCommand::run" << workingDirectory << arguments;
QProcess process;
if (!workingDirectory.isEmpty())
process.setWorkingDirectory(workingDirectory);
ProjectExplorer::Environment env = environment;
if (env.toStringList().isEmpty())
env = ProjectExplorer::Environment::systemEnvironment();
process.setEnvironment(env.toStringList());
process.start(QLatin1String(kGitCommand), arguments);
if (!process.waitForFinished()) {
emit errorText(QLatin1String("Error: Git timed out"));
return;
}
const QByteArray output = process.readAllStandardOutput();
if (output.isEmpty()) {
if (arguments.at(0) == QLatin1String("diff"))
emit outputText(tr("The file does not differ from HEAD"));
} else {
emit outputData(output);
}
const QByteArray error = process.readAllStandardError();
if (!error.isEmpty())
emit errorText(QString::fromLocal8Bit(error));
// As it is used asynchronously, we need to delete ourselves
this->deleteLater();
}