git: Reuse more code from vcsbase

Change-Id: I873d2caa2cead5c339eec887a5fcdef4d33bec24
Reviewed-on: http://codereview.qt-project.org/6071
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
This commit is contained in:
Tobias Hunger
2011-10-05 10:35:24 +00:00
parent f6068c1ff9
commit 363b230abf
15 changed files with 359 additions and 592 deletions
+1 -1
View File
@@ -144,7 +144,7 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizardPage::createCheckoutJob(
const QString checkoutDir = directory(); const QString checkoutDir = directory();
*checkoutPath = workingDirectory + QLatin1Char('/') + checkoutDir; *checkoutPath = workingDirectory + QLatin1Char('/') + checkoutDir;
const QString binary = client->binary(); const QString binary = client->gitBinaryPath();
VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob; VCSBase::ProcessCheckoutJob *job = new VCSBase::ProcessCheckoutJob;
const QProcessEnvironment env = client->processEnvironment(); const QProcessEnvironment env = client->processEnvironment();
+163 -348
View File
@@ -58,6 +58,7 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseeditorparameterwidget.h>
#include <vcsbase/vcsbaseoutputwindow.h> #include <vcsbase/vcsbaseoutputwindow.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
@@ -79,103 +80,50 @@ static const char kBranchIndicatorC[] = "# On branch";
namespace Git { namespace Git {
namespace Internal { namespace Internal {
BaseGitArgumentsWidget::BaseGitArgumentsWidget(GitSettings *settings, class BaseGitDiffArgumentsWidget : public VCSBase::VCSBaseEditorParameterWidget
Git::Internal::GitClient *client,
const QString &directory,
const QStringList &args) :
QWidget(0),
m_client(client),
m_workingDirectory(directory),
m_diffArgs(args),
m_settings(settings)
{
Q_ASSERT(settings);
Q_ASSERT(client);
}
class BaseGitDiffArgumentsWidget : public Git::Internal::BaseGitArgumentsWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
BaseGitDiffArgumentsWidget(Git::Internal::GitSettings *settings, BaseGitDiffArgumentsWidget(GitClient *client, const QString &directory,
Git::Internal::GitClient *client,
const QString &directory,
const QStringList &args) : const QStringList &args) :
BaseGitArgumentsWidget(settings, client, directory, args), m_workingDirectory(directory),
m_patience(new QToolButton), m_client(client),
m_ignoreSpaces(new QToolButton) m_args(args)
{ {
QHBoxLayout *layout = new QHBoxLayout(this); Q_ASSERT(!directory.isEmpty());
layout->setContentsMargins(3, 0, 3, 0); Q_ASSERT(m_client);
layout->setSpacing(2);
m_patience->setToolTip(tr("Use the patience algorithm for calculating the differences.")); mapSetting(addToggleButton(QLatin1String("--patience"), tr("Patience"),
m_patience->setText(tr("Patience")); tr("Use the patience algorithm for calculating the differences.")),
layout->addWidget(m_patience); client->settings()->boolPointer(GitSettings::diffPatienceKey));
m_patience->setCheckable(true); mapSetting(addToggleButton("--ignore-space-change", tr("Ignore Whitespace"),
m_patience->setChecked(m_settings->diffPatience); tr("Ignore whitespace only changes.")),
connect(m_patience, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged())); m_client->settings()->boolPointer(GitSettings::ignoreSpaceChangesInDiffKey));
m_ignoreSpaces->setToolTip(tr("Ignore whitespace only changes."));
m_ignoreSpaces->setText(tr("Ignore Whitespace"));
layout->addWidget(m_ignoreSpaces);
m_ignoreSpaces->setCheckable(true);
m_ignoreSpaces->setChecked(m_settings->ignoreSpaceChangesInDiff);
connect(m_ignoreSpaces, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged()));
}
QStringList arguments() const
{
QStringList args;
foreach (const QString &arg, m_diffArgs) {
if (arg == QLatin1String("--patience")
|| arg == QLatin1String("--ignore-space-change"))
continue;
args.append(arg);
}
if (m_patience->isChecked())
args.prepend(QLatin1String("--patience"));
if (m_ignoreSpaces->isChecked())
args.prepend(QLatin1String("--ignore-space-change"));
return args;
}
void testForArgumentsChanged() {
m_settings->diffPatience = m_patience->isChecked();
m_settings->ignoreSpaceChangesInDiff = m_ignoreSpaces->isChecked();
QStringList newArguments = arguments();
if (newArguments == m_diffArgs)
return;
m_diffArgs = newArguments;
redoCommand();
} }
protected: protected:
QToolButton *m_patience; QString m_workingDirectory;
QToolButton *m_ignoreSpaces; GitClient *m_client;
QStringList m_args;
}; };
class GitCommitDiffArgumentsWidget : public BaseGitDiffArgumentsWidget class GitCommitDiffArgumentsWidget : public BaseGitDiffArgumentsWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
GitCommitDiffArgumentsWidget(Git::Internal::GitSettings *settings, GitCommitDiffArgumentsWidget(Git::Internal::GitClient *client, const QString &directory,
Git::Internal::GitClient *client, const QString &directory,
const QStringList &args, const QStringList &unstaged, const QStringList &args, const QStringList &unstaged,
const QStringList &staged) : const QStringList &staged) :
BaseGitDiffArgumentsWidget(settings, client, directory, args), BaseGitDiffArgumentsWidget(client, directory, args),
m_unstagedFileNames(unstaged), m_unstagedFileNames(unstaged),
m_stagedFileNames(staged) m_stagedFileNames(staged)
{ } { }
void redoCommand() void executeCommand()
{ {
m_client->diff(m_workingDirectory, m_diffArgs, m_unstagedFileNames, m_stagedFileNames); m_client->diff(m_workingDirectory, m_args, m_unstagedFileNames, m_stagedFileNames);
} }
private: private:
@@ -187,16 +135,15 @@ class GitFileDiffArgumentsWidget : public BaseGitDiffArgumentsWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
GitFileDiffArgumentsWidget(Git::Internal::GitSettings *settings, GitFileDiffArgumentsWidget(Git::Internal::GitClient *client, const QString &directory,
Git::Internal::GitClient *client, const QString &directory,
const QStringList &args, const QString &file) : const QStringList &args, const QString &file) :
BaseGitDiffArgumentsWidget(settings, client, directory, args), BaseGitDiffArgumentsWidget(client, directory, args),
m_fileName(file) m_fileName(file)
{ } { }
void redoCommand() void executeCommand()
{ {
m_client->diff(m_workingDirectory, m_diffArgs, m_fileName); m_client->diff(m_workingDirectory, m_args, m_fileName);
} }
private: private:
@@ -207,128 +154,81 @@ class GitBranchDiffArgumentsWidget : public BaseGitDiffArgumentsWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
GitBranchDiffArgumentsWidget(Git::Internal::GitSettings *settings, GitBranchDiffArgumentsWidget(Git::Internal::GitClient *client, const QString &directory,
Git::Internal::GitClient *client, const QString &directory,
const QStringList &args, const QString &branch) : const QStringList &args, const QString &branch) :
BaseGitDiffArgumentsWidget(settings, client, directory, args), BaseGitDiffArgumentsWidget(client, directory, args),
m_branchName(branch) m_branchName(branch)
{ } { }
void redoCommand() void redoCommand()
{ {
m_client->diffBranch(m_workingDirectory, m_diffArgs, m_branchName); m_client->diffBranch(m_workingDirectory, m_args, m_branchName);
} }
private: private:
const QString m_branchName; const QString m_branchName;
}; };
class GitShowArgumentsWidget : public Git::Internal::BaseGitArgumentsWidget class GitShowArgumentsWidget : public VCSBase::VCSBaseEditorParameterWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
GitShowArgumentsWidget(Git::Internal::GitSettings *settings, GitShowArgumentsWidget(Git::Internal::GitClient *client,
Git::Internal::GitClient *client,
const QString &directory, const QString &directory,
const QStringList &args, const QStringList &args,
const QString &id) : const QString &id) :
BaseGitArgumentsWidget(settings, client, directory, args), m_client(client),
m_prettyFormat(new QComboBox), m_workingDirectory(directory),
m_args(args),
m_id(id) m_id(id)
{ {
QHBoxLayout *layout = new QHBoxLayout(this); QList<ComboBoxItem> prettyChoices;
layout->setContentsMargins(3, 0, 3, 0); prettyChoices << ComboBoxItem(tr("oneline"), QLatin1String("oneline"))
layout->setSpacing(2); << ComboBoxItem(tr("short"), QLatin1String("short"))
<< ComboBoxItem(tr("medium"), QLatin1String("medium"))
m_prettyFormat->setToolTip(tr("Select the pretty printing format.")); << ComboBoxItem(tr("full"), QLatin1String("full"))
m_prettyFormat->addItem(tr("oneline"), QLatin1String("oneline")); << ComboBoxItem(tr("fuller"), QLatin1String("fuller"))
m_prettyFormat->addItem(tr("short"), QLatin1String("short")); << ComboBoxItem(tr("email"), QLatin1String("email"))
m_prettyFormat->addItem(tr("medium"), QLatin1String("medium")); << ComboBoxItem(tr("raw"), QLatin1String("raw"));
m_prettyFormat->addItem(tr("full"), QLatin1String("full")); mapSetting(addComboBox(QLatin1String("--pretty"), prettyChoices),
m_prettyFormat->addItem(tr("fuller"), QLatin1String("fuller")); m_client->settings()->stringPointer(GitSettings::showPrettyFormatKey));
m_prettyFormat->addItem(tr("email"), QLatin1String("email"));
m_prettyFormat->addItem(tr("raw"), QLatin1String("raw"));
layout->addWidget(m_prettyFormat);
m_prettyFormat->setCurrentIndex(m_settings->showPrettyFormat);
m_prettyFormat->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
connect(m_prettyFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(testForArgumentsChanged()));
} }
QStringList arguments() const void executeCommand()
{ {
QStringList args; m_client->show(m_workingDirectory, m_id, m_args);
foreach (const QString &arg, m_diffArgs) {
if (arg.startsWith(QLatin1String("--pretty=")) || arg.startsWith(QLatin1String("--format=")))
continue;
args.append(arg);
}
args.prepend(QString::fromLatin1("--pretty=")
+ m_prettyFormat->itemData(m_prettyFormat->currentIndex()).toString());
return args;
}
void testForArgumentsChanged() {
m_settings->showPrettyFormat = m_prettyFormat->currentIndex();
QStringList newArguments = arguments();
if (newArguments == m_diffArgs)
return;
m_diffArgs = newArguments;
redoCommand();
}
void redoCommand()
{
m_client->show(m_workingDirectory, m_id, m_diffArgs);
} }
private: private:
QComboBox *m_prettyFormat; GitClient *m_client;
QString m_workingDirectory;
QStringList m_args;
QString m_id; QString m_id;
}; };
class GitBlameArgumentsWidget : public Git::Internal::BaseGitArgumentsWidget class GitBlameArgumentsWidget : public VCSBase::VCSBaseEditorParameterWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
GitBlameArgumentsWidget(Git::Internal::GitSettings *settings, GitBlameArgumentsWidget(Git::Internal::GitClient *client,
Git::Internal::GitClient *client, const QString &directory, const QString &directory,
const QStringList &args, const QString &revision, const QStringList &args,
const QString &fileName) : const QString &revision, const QString &fileName) :
Git::Internal::BaseGitArgumentsWidget(settings, client, directory, args),
m_omitDate(0),
m_ignoreSpaces(0),
m_editor(0), m_editor(0),
m_client(client),
m_workingDirectory(directory),
m_args(args),
m_revision(revision), m_revision(revision),
m_fileName(fileName) m_fileName(fileName)
{ {
QHBoxLayout *layout = new QHBoxLayout(this); mapSetting(addToggleButton(QString(), tr("Omit Date"),
layout->setContentsMargins(3, 0, 3, 0); tr("Hide the date of a change from the output.")),
layout->setSpacing(2); m_client->settings()->boolPointer(GitSettings::omitAnnotationDateKey));
mapSetting(addToggleButton(QString("-w"), tr("Ignore Whitespace"),
m_omitDate = new QToolButton; tr("Ignore whitespace only changes.")),
m_omitDate->setToolTip(tr("Hide the date of a change from the output.")); m_client->settings()->boolPointer(GitSettings::ignoreSpaceChangesInBlameKey));
m_omitDate->setText(tr("Omit Date"));
layout->addWidget(m_omitDate);
m_omitDate->setCheckable(true);
m_omitDate->setChecked(m_settings->omitAnnotationDate);
m_omitDate->setMinimumHeight(16);
m_omitDate->setMaximumHeight(16);
connect(m_omitDate, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged()));
m_ignoreSpaces = new QToolButton;
m_ignoreSpaces->setToolTip(tr("Ignore whitespace only changes."));
m_ignoreSpaces->setText(tr("Ignore Whitespace"));
layout->addWidget(m_ignoreSpaces);
m_ignoreSpaces->setCheckable(true);
m_ignoreSpaces->setChecked(m_settings->ignoreSpaceChangesInBlame);
m_ignoreSpaces->setMinimumHeight(16);
m_ignoreSpaces->setMaximumHeight(16);
connect(m_ignoreSpaces, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged()));
} }
void setEditor(VCSBase::VCSBaseEditorWidget *editor) void setEditor(VCSBase::VCSBaseEditorWidget *editor)
@@ -337,36 +237,19 @@ public:
m_editor = editor; m_editor = editor;
} }
QStringList arguments() const void executeCommand()
{ {
QStringList args = m_diffArgs; int line = -1;
if (m_editor)
args.removeAll(QLatin1String("-w")); line = m_editor->lineNumberOfCurrentEditor();
m_client->blame(m_workingDirectory, m_args, m_fileName, m_revision, line);
if (m_ignoreSpaces->isChecked())
args.prepend(QLatin1String("-w"));
return args;
}
void testForArgumentsChanged() {
m_settings->omitAnnotationDate = m_omitDate->isChecked();
m_settings->ignoreSpaceChangesInBlame = m_ignoreSpaces->isChecked();
m_diffArgs = arguments();
redoCommand(); // always redo for omit date
}
void redoCommand()
{
m_client->blame(m_workingDirectory, m_diffArgs, m_fileName,
m_revision, m_editor->lineNumberOfCurrentEditor());
} }
private: private:
QToolButton *m_omitDate;
QToolButton *m_ignoreSpaces;
VCSBase::VCSBaseEditorWidget *m_editor; VCSBase::VCSBaseEditorWidget *m_editor;
GitClient *m_client;
QString m_workingDirectory;
QStringList m_args;
QString m_revision; QString m_revision;
QString m_fileName; QString m_fileName;
}; };
@@ -418,18 +301,14 @@ static inline QString msgParseFilesFailed()
const char *GitClient::stashNamePrefix = "stash@{"; const char *GitClient::stashNamePrefix = "stash@{";
GitClient::GitClient(GitPlugin* plugin) : GitClient::GitClient(GitSettings *settings) :
m_cachedGitVersion(0),
m_msgWait(tr("Waiting for data...")), m_msgWait(tr("Waiting for data...")),
m_plugin(plugin),
m_core(Core::ICore::instance()), m_core(Core::ICore::instance()),
m_repositoryChangedSignalMapper(0), m_repositoryChangedSignalMapper(0),
m_cachedGitVersion(0), m_settings(settings)
m_hasCachedGitVersion(false)
{ {
if (QSettings *s = m_core->settings()) { Q_ASSERT(settings);
m_settings.fromSettings(s);
m_binaryPath = m_settings.gitBinaryPath();
}
} }
GitClient::~GitClient() GitClient::~GitClient()
@@ -462,7 +341,6 @@ VCSBase::VCSBaseEditorWidget *GitClient::findExistingVCSEditor(const char *regis
return rc; return rc;
} }
/* Create an editor associated to VCS output of a source file/directory /* Create an editor associated to VCS output of a source file/directory
* (using the file's codec). Makes use of a dynamic property to find an * (using the file's codec). Makes use of a dynamic property to find an
* existing instance and to reuse it (in case, say, 'git diff foo' is * existing instance and to reuse it (in case, say, 'git diff foo' is
@@ -505,19 +383,19 @@ void GitClient::diff(const QString &workingDirectory,
const QStringList &unstagedFileNames, const QStringList &unstagedFileNames,
const QStringList &stagedFileNames) const QStringList &stagedFileNames)
{ {
const QString binary = QLatin1String(Constants::GIT_BINARY); const QString binary = settings()->stringValue(GitSettings::binaryPathKey);
const QString editorId = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_ID); const QString editorId = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_ID);
const QString title = tr("Git Diff"); const QString title = tr("Git Diff");
VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", workingDirectory); VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", workingDirectory);
if (!editor) { if (!editor) {
GitCommitDiffArgumentsWidget *argWidget = GitCommitDiffArgumentsWidget *argWidget =
new GitCommitDiffArgumentsWidget(&m_settings, this, workingDirectory, diffArgs, new GitCommitDiffArgumentsWidget(this, workingDirectory, diffArgs,
unstagedFileNames, stagedFileNames); unstagedFileNames, stagedFileNames);
editor = createVCSEditor(editorId, title, editor = createVCSEditor(editorId, title,
workingDirectory, true, "originalFileName", workingDirectory, argWidget); workingDirectory, true, "originalFileName", workingDirectory, argWidget);
connect(editor, SIGNAL(diffChunkReverted(VCSBase::DiffChunk)), argWidget, SLOT(redoCommand())); connect(editor, SIGNAL(diffChunkReverted(VCSBase::DiffChunk)), argWidget, SLOT(executeCommand()));
editor->setRevertDiffChunkEnabled(true); editor->setRevertDiffChunkEnabled(true);
} }
@@ -534,11 +412,13 @@ void GitClient::diff(const QString &workingDirectory,
QStringList cmdArgs; QStringList cmdArgs;
cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption); cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption);
int timeout = settings()->intValue(GitSettings::timeoutKey);
if (unstagedFileNames.empty() && stagedFileNames.empty()) { if (unstagedFileNames.empty() && stagedFileNames.empty()) {
QStringList arguments(cmdArgs); QStringList arguments(cmdArgs);
arguments << userDiffArgs; arguments << userDiffArgs;
outputWindow()->appendCommand(workingDirectory, binary, arguments); outputWindow()->appendCommand(workingDirectory, binary, arguments);
command->addJob(arguments, m_settings.timeoutSeconds); command->addJob(arguments, timeout);
} else { } else {
// Files diff. // Files diff.
if (!unstagedFileNames.empty()) { if (!unstagedFileNames.empty()) {
@@ -546,14 +426,14 @@ void GitClient::diff(const QString &workingDirectory,
arguments << userDiffArgs; arguments << userDiffArgs;
arguments << QLatin1String("--") << unstagedFileNames; arguments << QLatin1String("--") << unstagedFileNames;
outputWindow()->appendCommand(workingDirectory, binary, arguments); outputWindow()->appendCommand(workingDirectory, binary, arguments);
command->addJob(arguments, m_settings.timeoutSeconds); command->addJob(arguments, timeout);
} }
if (!stagedFileNames.empty()) { if (!stagedFileNames.empty()) {
QStringList arguments(cmdArgs); QStringList arguments(cmdArgs);
arguments << userDiffArgs; arguments << userDiffArgs;
arguments << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames; arguments << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames;
outputWindow()->appendCommand(workingDirectory, binary, arguments); outputWindow()->appendCommand(workingDirectory, binary, arguments);
command->addJob(arguments, m_settings.timeoutSeconds); command->addJob(arguments, timeout);
} }
} }
command->execute(); command->execute();
@@ -570,11 +450,10 @@ void GitClient::diff(const QString &workingDirectory,
VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", sourceFile); VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", sourceFile);
if (!editor) { if (!editor) {
GitFileDiffArgumentsWidget *argWidget = GitFileDiffArgumentsWidget *argWidget =
new GitFileDiffArgumentsWidget(&m_settings, this, workingDirectory, new GitFileDiffArgumentsWidget(this, workingDirectory, diffArgs, fileName);
diffArgs, fileName);
editor = createVCSEditor(editorId, title, sourceFile, true, "originalFileName", sourceFile, argWidget); editor = createVCSEditor(editorId, title, sourceFile, true, "originalFileName", sourceFile, argWidget);
connect(editor, SIGNAL(diffChunkReverted(VCSBase::DiffChunk)), argWidget, SLOT(redoCommand())); connect(editor, SIGNAL(diffChunkReverted(VCSBase::DiffChunk)), argWidget, SLOT(executeCommand()));
editor->setRevertDiffChunkEnabled(true); editor->setRevertDiffChunkEnabled(true);
} }
@@ -601,7 +480,7 @@ void GitClient::diffBranch(const QString &workingDirectory,
VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("BranchName", branchName); VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("BranchName", branchName);
if (!editor) if (!editor)
editor = createVCSEditor(editorId, title, sourceFile, true, "BranchName", branchName, editor = createVCSEditor(editorId, title, sourceFile, true, "BranchName", branchName,
new GitBranchDiffArgumentsWidget(&m_settings, this, workingDirectory, new GitBranchDiffArgumentsWidget(this, workingDirectory,
diffArgs, branchName)); diffArgs, branchName));
GitBranchDiffArgumentsWidget *argWidget = qobject_cast<GitBranchDiffArgumentsWidget *>(editor->configurationWidget()); GitBranchDiffArgumentsWidget *argWidget = qobject_cast<GitBranchDiffArgumentsWidget *>(editor->configurationWidget());
@@ -634,8 +513,9 @@ void GitClient::graphLog(const QString &workingDirectory, const QString & branch
QStringList arguments; QStringList arguments;
arguments << QLatin1String("log") << QLatin1String(noColorOption); arguments << QLatin1String("log") << QLatin1String(noColorOption);
if (m_settings.logCount > 0) int logCount = settings()->intValue(GitSettings::logCountKey);
arguments << QLatin1String("-n") << QString::number(m_settings.logCount); if (logCount > 0)
arguments << QLatin1String("-n") << QString::number(logCount);
arguments << (QLatin1String("--pretty=format:") + QLatin1String(graphLogFormatC)) arguments << (QLatin1String("--pretty=format:") + QLatin1String(graphLogFormatC))
<< QLatin1String("--topo-order") << QLatin1String("--graph"); << QLatin1String("--topo-order") << QLatin1String("--graph");
@@ -654,14 +534,16 @@ void GitClient::graphLog(const QString &workingDirectory, const QString & branch
executeGit(workingDirectory, arguments, editor); executeGit(workingDirectory, arguments, editor);
} }
void GitClient::log(const QString &workingDirectory, const QStringList &fileNames, bool enableAnnotationContextMenu) void GitClient::log(const QString &workingDirectory, const QStringList &fileNames,
bool enableAnnotationContextMenu)
{ {
QStringList arguments; QStringList arguments;
arguments << QLatin1String("log") << QLatin1String(noColorOption) arguments << QLatin1String("log") << QLatin1String(noColorOption)
<< QLatin1String(decorateOption); << QLatin1String(decorateOption);
if (m_settings.logCount > 0) int logCount = settings()->intValue(GitSettings::logCountKey);
arguments << QLatin1String("-n") << QString::number(m_settings.logCount); if (logCount > 0)
arguments << QLatin1String("-n") << QString::number(logCount);
if (!fileNames.isEmpty()) if (!fileNames.isEmpty())
arguments.append(fileNames); arguments.append(fileNames);
@@ -705,7 +587,7 @@ void GitClient::show(const QString &source, const QString &id, const QStringList
VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("show", id); VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("show", id);
if (!editor) if (!editor)
editor = createVCSEditor(editorId, title, source, true, "show", id, editor = createVCSEditor(editorId, title, source, true, "show", id,
new GitShowArgumentsWidget(&m_settings, this, source, args, id)); new GitShowArgumentsWidget(this, source, args, id));
GitShowArgumentsWidget *argWidget = qobject_cast<GitShowArgumentsWidget *>(editor->configurationWidget()); GitShowArgumentsWidget *argWidget = qobject_cast<GitShowArgumentsWidget *>(editor->configurationWidget());
QStringList userArgs = argWidget->arguments(); QStringList userArgs = argWidget->arguments();
@@ -746,7 +628,7 @@ void GitClient::blame(const QString &workingDirectory,
VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("blameFileName", id); VCSBase::VCSBaseEditorWidget *editor = findExistingVCSEditor("blameFileName", id);
if (!editor) { if (!editor) {
GitBlameArgumentsWidget *argWidget = GitBlameArgumentsWidget *argWidget =
new GitBlameArgumentsWidget(&m_settings, this, workingDirectory, args, new GitBlameArgumentsWidget(this, workingDirectory, args,
revision, fileName); revision, fileName);
editor = createVCSEditor(editorId, title, sourceFile, true, "blameFileName", id, argWidget); editor = createVCSEditor(editorId, title, sourceFile, true, "blameFileName", id, argWidget);
argWidget->setEditor(editor); argWidget->setEditor(editor);
@@ -899,19 +781,17 @@ bool GitClient::synchronousReset(const QString &workingDirectory,
QByteArray errorText; QByteArray errorText;
QStringList arguments; QStringList arguments;
arguments << QLatin1String("reset"); arguments << QLatin1String("reset");
if (files.isEmpty()) { if (files.isEmpty())
arguments << QLatin1String("--hard"); arguments << QLatin1String("--hard");
} else { else
arguments << QLatin1String("HEAD") << QLatin1String("--") << files; arguments << QLatin1String("HEAD") << QLatin1String("--") << files;
}
const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText); const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText);
const QString output = commandOutputFromLocal8Bit(outputText); const QString output = commandOutputFromLocal8Bit(outputText);
outputWindow()->append(output); outputWindow()->append(output);
// Note that git exits with 1 even if the operation is successful // Note that git exits with 1 even if the operation is successful
// Assume real failure if the output does not contain "foo.cpp modified" // Assume real failure if the output does not contain "foo.cpp modified"
// or "Unstaged changes after reset" (git 1.7.0). // or "Unstaged changes after reset" (git 1.7.0).
if (!rc && if (!rc && (!output.contains(QLatin1String("modified"))
(!output.contains(QLatin1String("modified"))
&& !output.contains(QLatin1String("Unstaged changes after reset")))) { && !output.contains(QLatin1String("Unstaged changes after reset")))) {
const QString stdErr = commandOutputFromLocal8Bit(errorText); const QString stdErr = commandOutputFromLocal8Bit(errorText);
const QString msg = files.isEmpty() ? const QString msg = files.isEmpty() ?
@@ -1378,23 +1258,21 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory,
bool outputToWindow, bool outputToWindow,
int editorLineNumber) int editorLineNumber)
{ {
VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); GitCommand *command = new GitCommand(gitBinaryPath(), workingDirectory, processEnvironment(), QVariant(editorLineNumber));
GitCommand* command = new GitCommand(binary(), workingDirectory, processEnvironment(), QVariant(editorLineNumber));
if (editor) if (editor)
connect(command, SIGNAL(finished(bool,int,QVariant)), editor, SLOT(commandFinishedGotoLine(bool,int,QVariant))); connect(command, SIGNAL(finished(bool,int,QVariant)), editor, SLOT(commandFinishedGotoLine(bool,int,QVariant)));
if (outputToWindow) { if (useOutputToWindow) {
if (editor) { // assume that the commands output is the important thing if (editor) // assume that the commands output is the important thing
connect(command, SIGNAL(outputData(QByteArray)), outputWindow, SLOT(appendDataSilently(QByteArray))); connect(command, SIGNAL(outputData(QByteArray)), outputWindow(), SLOT(appendDataSilently(QByteArray)));
} else { else
connect(command, SIGNAL(outputData(QByteArray)), outputWindow, SLOT(appendData(QByteArray))); connect(command, SIGNAL(outputData(QByteArray)), outputWindow(), SLOT(appendData(QByteArray)));
}
} else { } else {
QTC_CHECK(editor); if (editor)
connect(command, SIGNAL(outputData(QByteArray)), editor, SLOT(setPlainTextDataFiltered(QByteArray))); connect(command, SIGNAL(outputData(QByteArray)), editor, SLOT(setPlainTextDataFiltered(QByteArray)));
} }
if (outputWindow) if (outputWindow())
connect(command, SIGNAL(errorText(QString)), outputWindow, SLOT(appendError(QString))); connect(command, SIGNAL(errorText(QString)), outputWindow(), SLOT(appendError(QString)));
return command; return command;
} }
@@ -1402,49 +1280,29 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory,
GitCommand *GitClient::executeGit(const QString &workingDirectory, GitCommand *GitClient::executeGit(const QString &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
VCSBase::VCSBaseEditorWidget* editor, VCSBase::VCSBaseEditorWidget* editor,
bool outputToWindow, bool useOutputToWindow,
GitCommand::TerminationReportMode tm, GitCommand::TerminationReportMode tm,
int editorLineNumber, int editorLineNumber,
bool unixTerminalDisabled) bool unixTerminalDisabled)
{ {
outputWindow()->appendCommand(workingDirectory, QLatin1String(Constants::GIT_BINARY), arguments); outputWindow()->appendCommand(workingDirectory, settings()->stringValue(GitSettings::binaryPathKey), arguments);
GitCommand *command = createCommand(workingDirectory, editor, outputToWindow, editorLineNumber); GitCommand *command = createCommand(workingDirectory, editor, useOutputToWindow, editorLineNumber);
command->addJob(arguments, m_settings.timeoutSeconds); command->addJob(arguments, settings()->intValue(GitSettings::timeoutKey));
command->setTerminationReportMode(tm); command->setTerminationReportMode(tm);
command->setUnixTerminalDisabled(unixTerminalDisabled); command->setUnixTerminalDisabled(unixTerminalDisabled);
command->execute(); command->execute();
return command; return command;
} }
// Return fixed arguments required to run
QString GitClient::binary() const
{
return m_binaryPath;
}
// Determine a value for the HOME variable on Windows
// working around MSys git not finding it when run outside git bash
// (then looking for the SSH keys under "\program files\git").
QString GitClient::fakeWinHome(const QProcessEnvironment &e)
{
const QString homeDrive = e.value("HOMEDRIVE");
const QString homePath = e.value("HOMEPATH");
QTC_ASSERT(!homeDrive.isEmpty() && !homePath.isEmpty(), return QString())
return homeDrive + homePath;
}
QProcessEnvironment GitClient::processEnvironment() const QProcessEnvironment GitClient::processEnvironment() const
{ {
QProcessEnvironment environment = QProcessEnvironment::systemEnvironment(); QProcessEnvironment environment = QProcessEnvironment::systemEnvironment();
if (m_settings.adoptPath) if (settings()->boolValue(GitSettings::adoptPathKey))
environment.insert(QLatin1String("PATH"), m_settings.path); environment.insert(QLatin1String("PATH"), settings()->stringValue(GitSettings::pathKey));
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (m_settings.winSetHomeEnvironment) { if (settings()->boolValue(GitSettings::winSetHomeEnvironmentKey))
const QString home = fakeWinHome(environment); environment.insert(QLatin1String("HOME"), QDir::toNativeSeparators(QDir::homePath()));
environment.insert(QLatin1String("HOME"), home);
}
#endif // Q_OS_WIN #endif // Q_OS_WIN
// Set up SSH and C locale (required by git using perl). // Set up SSH and C locale (required by git using perl).
VCSBase::VCSBasePlugin::setProcessEnvironment(&environment, false); VCSBase::VCSBasePlugin::setProcessEnvironment(&environment, false);
@@ -1458,8 +1316,8 @@ Utils::SynchronousProcessResponse GitClient::synchronousGit(const QString &worki
unsigned flags, unsigned flags,
QTextCodec *stdOutCodec) QTextCodec *stdOutCodec)
{ {
return VCSBase::VCSBasePlugin::runVCS(workingDirectory, binary(), gitArguments, return VCSBase::VCSBasePlugin::runVCS(workingDirectory, gitBinaryPath(), gitArguments,
m_settings.timeoutSeconds * 1000, settings()->intValue(GitSettings::timeoutKey) * 1000,
processEnvironment(), processEnvironment(),
flags, stdOutCodec); flags, stdOutCodec);
} }
@@ -1468,34 +1326,12 @@ bool GitClient::fullySynchronousGit(const QString &workingDirectory,
const QStringList &gitArguments, const QStringList &gitArguments,
QByteArray* outputText, QByteArray* outputText,
QByteArray* errorText, QByteArray* errorText,
bool logCommandToWindow) bool logCommandToWindow) const
{ {
if (logCommandToWindow) return VCSBase::VCSBasePlugin::runFullySynchronous(workingDirectory, gitBinaryPath(), gitArguments,
outputWindow()->appendCommand(workingDirectory, m_binaryPath, gitArguments); processEnvironment(), outputText, errorText,
settings()->intValue(GitSettings::timeoutKey) * 1000,
QProcess process; logCommandToWindow);
process.setWorkingDirectory(workingDirectory);
process.setProcessEnvironment(processEnvironment());
process.start(binary(), gitArguments);
process.closeWriteChannel();
if (!process.waitForStarted()) {
if (errorText) {
const QString msg = QString::fromLatin1("Unable to execute '%1': %2:")
.arg(binary(), process.errorString());
*errorText = msg.toLocal8Bit();
}
return false;
}
if (!Utils::SynchronousProcess::readDataFromProcess(process, m_settings.timeoutSeconds * 1000,
outputText, errorText, true)) {
errorText->append(GitCommand::msgTimeout(m_settings.timeoutSeconds).toLocal8Bit());
Utils::SynchronousProcess::stopProcess(process);
return false;
}
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
} }
static inline int askWithDetailedText(QWidget *parent, static inline int askWithDetailedText(QWidget *parent,
@@ -1640,27 +1476,16 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR
void GitClient::launchGitK(const QString &workingDirectory) void GitClient::launchGitK(const QString &workingDirectory)
{ {
VCSBase::VCSBaseOutputWindow *outwin = VCSBase::VCSBaseOutputWindow::instance(); const QString gitBinDirectory = gitBinaryPath();
// Locate git in (potentially) custom path. m_binaryPath can be absolute, QDir foundBinDir(gitBinDirectory);
// which will be handled correctly.
QTC_ASSERT(!m_binaryPath.isEmpty(), return);
const QString gitBinary = QLatin1String(Constants::GIT_BINARY);
const QProcessEnvironment env = processEnvironment();
const QString path = env.value(QLatin1String("PATH"));
const QString fullGitBinary = Utils::SynchronousProcess::locateBinary(path, m_binaryPath);
if (fullGitBinary.isEmpty()) {
outwin->appendError(tr("Cannot locate \"%1\".").arg(gitBinary));
return;
}
const QString gitBinDirectory = QFileInfo(fullGitBinary).absolutePath();
QDir foundBinDir = gitBinDirectory;
const bool foundBinDirIsCmdDir = foundBinDir.dirName() == "cmd"; const bool foundBinDirIsCmdDir = foundBinDir.dirName() == "cmd";
if (!tryLauchingGitK(env, workingDirectory, gitBinDirectory, foundBinDirIsCmdDir)) { QProcessEnvironment env = processEnvironment();
if (foundBinDirIsCmdDir) { if (tryLauchingGitK(env, workingDirectory, gitBinDirectory, foundBinDirIsCmdDir))
foundBinDir.cdUp(); return;
tryLauchingGitK(env, workingDirectory, foundBinDir.path() + "/bin", false); if (!foundBinDirIsCmdDir)
} return;
} foundBinDir.cdUp();
tryLauchingGitK(env, workingDirectory, foundBinDir.path() + "/bin", false);
} }
bool GitClient::tryLauchingGitK(const QProcessEnvironment &env, bool GitClient::tryLauchingGitK(const QProcessEnvironment &env,
@@ -1678,13 +1503,14 @@ bool GitClient::tryLauchingGitK(const QProcessEnvironment &env,
QStringList arguments; QStringList arguments;
#endif #endif
VCSBase::VCSBaseOutputWindow *outwin = VCSBase::VCSBaseOutputWindow::instance(); VCSBase::VCSBaseOutputWindow *outwin = VCSBase::VCSBaseOutputWindow::instance();
if (!m_settings.gitkOptions.isEmpty()) const QString gitkOpts = settings()->stringValue(GitSettings::gitkOptionsKey);
arguments.append(Utils::QtcProcess::splitArgs(m_settings.gitkOptions)); if (!gitkOpts.isEmpty())
arguments.append(Utils::QtcProcess::splitArgs(gitkOpts));
outwin->appendCommand(workingDirectory, binary, arguments); outwin->appendCommand(workingDirectory, binary, arguments);
// This should always use QProcess::startDetached (as not to kill // This should always use QProcess::startDetached (as not to kill
// the child), but that does not have an environment parameter. // the child), but that does not have an environment parameter.
bool success = false; bool success = false;
if (m_settings.adoptPath) { if (settings()->boolValue(GitSettings::adoptPathKey)) {
QProcess *process = new QProcess(this); QProcess *process = new QProcess(this);
process->setWorkingDirectory(workingDirectory); process->setWorkingDirectory(workingDirectory);
process->setProcessEnvironment(env); process->setProcessEnvironment(env);
@@ -1707,6 +1533,11 @@ bool GitClient::tryLauchingGitK(const QProcessEnvironment &env,
return success; return success;
} }
QString GitClient::gitBinaryPath(bool *ok, QString *errorMessage) const
{
return settings()->gitBinaryPath(ok, errorMessage);
}
bool GitClient::getCommitData(const QString &workingDirectory, bool GitClient::getCommitData(const QString &workingDirectory,
bool amend, bool amend,
QString *commitTemplate, QString *commitTemplate,
@@ -1870,14 +1701,12 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
// for deletion. Purge out renamed files ('foo.cpp -> foo2.cpp'). // for deletion. Purge out renamed files ('foo.cpp -> foo2.cpp').
QStringList addFiles = checkedFiles.toSet().subtract(origDeletedFiles.toSet()).toList(); QStringList addFiles = checkedFiles.toSet().subtract(origDeletedFiles.toSet()).toList();
for (QStringList::iterator it = addFiles.begin(); it != addFiles.end(); ) { for (QStringList::iterator it = addFiles.begin(); it != addFiles.end(); ) {
if (it->contains(renamedSeparator)) { if (it->contains(renamedSeparator))
it = addFiles.erase(it); it = addFiles.erase(it);
} else { else
++it; ++it;
}
} }
if (!addFiles.isEmpty()) if (!addFiles.isEmpty() && !synchronousAdd(repositoryDirectory, false, addFiles))
if (!synchronousAdd(repositoryDirectory, false, addFiles))
return false; return false;
// Do the final commit // Do the final commit
@@ -1893,11 +1722,10 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
QByteArray outputText; QByteArray outputText;
QByteArray errorText; QByteArray errorText;
const bool rc = fullySynchronousGit(repositoryDirectory, args, &outputText, &errorText); const bool rc = fullySynchronousGit(repositoryDirectory, args, &outputText, &errorText);
if (rc) { if (rc)
outputWindow()->append(msgCommitted(amendSHA1, checkedFiles.size())); outputWindow()->append(msgCommitted(amendSHA1, checkedFiles.size()));
} else { else
outputWindow()->appendError(tr("Cannot commit %n file(s): %1\n", 0, checkedFiles.size()).arg(commandOutputFromLocal8Bit(errorText))); outputWindow()->appendError(tr("Cannot commit %n file(s): %1\n", 0, checkedFiles.size()).arg(commandOutputFromLocal8Bit(errorText)));
}
return rc; return rc;
} }
@@ -1906,7 +1734,6 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
* 'revert single' in its VCS menus, but the code is prepared to deal with * 'revert single' in its VCS menus, but the code is prepared to deal with
* reverting a directory pending a sophisticated selection dialog in the * reverting a directory pending a sophisticated selection dialog in the
* VCSBase plugin. */ * VCSBase plugin. */
GitClient::RevertResult GitClient::revertI(QStringList files, GitClient::RevertResult GitClient::revertI(QStringList files,
bool *ptrToIsDirectory, bool *ptrToIsDirectory,
QString *errorMessage, QString *errorMessage,
@@ -1997,7 +1824,7 @@ void GitClient::revert(const QStringList &files, bool revertStaging)
QString errorMessage; QString errorMessage;
switch (revertI(files, &isDirectory, &errorMessage, revertStaging)) { switch (revertI(files, &isDirectory, &errorMessage, revertStaging)) {
case RevertOk: case RevertOk:
m_plugin->gitVersionControl()->emitFilesChanged(files); GitPlugin::instance()->gitVersionControl()->emitFilesChanged(files);
break; break;
case RevertCanceled: case RevertCanceled:
break; break;
@@ -2026,7 +1853,7 @@ bool GitClient::synchronousFetch(const QString &workingDirectory, const QString
bool GitClient::synchronousPull(const QString &workingDirectory) bool GitClient::synchronousPull(const QString &workingDirectory)
{ {
return synchronousPull(workingDirectory, m_settings.pullRebase); return synchronousPull(workingDirectory, settings()->boolValue(GitSettings::pullRebaseKey));
} }
bool GitClient::synchronousPull(const QString &workingDirectory, bool rebase) bool GitClient::synchronousPull(const QString &workingDirectory, bool rebase)
@@ -2081,8 +1908,9 @@ void GitClient::subversionLog(const QString &workingDirectory)
{ {
QStringList arguments; QStringList arguments;
arguments << QLatin1String("svn") << QLatin1String("log"); arguments << QLatin1String("svn") << QLatin1String("log");
if (m_settings.logCount > 0) int logCount = settings()->intValue(GitSettings::logCountKey);
arguments << (QLatin1String("--limit=") + QString::number(m_settings.logCount)); if (logCount > 0)
arguments << (QLatin1String("--limit=") + QString::number(logCount));
// Create a command editor, no highlighting or interaction. // Create a command editor, no highlighting or interaction.
const QString title = tr("Git SVN Log"); const QString title = tr("Git SVN Log");
@@ -2307,31 +2135,18 @@ QString GitClient::vcsGetRepositoryURL(const QString &directory)
return QString(); return QString();
} }
GitSettings GitClient::settings() const GitSettings *GitClient::settings() const
{ {
return m_settings; return m_settings;
} }
void GitClient::setSettings(const GitSettings &s)
{
if (s != m_settings) {
m_settings = s;
if (QSettings *coreSettings = m_core->settings())
m_settings.toSettings(coreSettings);
m_binaryPath = m_settings.gitBinaryPath();
m_cachedGitVersion = 0u;
m_hasCachedGitVersion = false;
m_plugin->gitVersionControl()->emitConfigurationChanged();
}
}
void GitClient::connectRepositoryChanged(const QString & repository, GitCommand *cmd) void GitClient::connectRepositoryChanged(const QString & repository, GitCommand *cmd)
{ {
// Bind command success termination with repository to changed signal // Bind command success termination with repository to changed signal
if (!m_repositoryChangedSignalMapper) { if (!m_repositoryChangedSignalMapper) {
m_repositoryChangedSignalMapper = new QSignalMapper(this); m_repositoryChangedSignalMapper = new QSignalMapper(this);
connect(m_repositoryChangedSignalMapper, SIGNAL(mapped(QString)), connect(m_repositoryChangedSignalMapper, SIGNAL(mapped(QString)),
m_plugin->gitVersionControl(), SIGNAL(repositoryChanged(QString))); GitPlugin::instance()->gitVersionControl(), SIGNAL(repositoryChanged(QString)));
} }
m_repositoryChangedSignalMapper->setMapping(cmd, repository); m_repositoryChangedSignalMapper->setMapping(cmd, repository);
connect(cmd, SIGNAL(success()), m_repositoryChangedSignalMapper, SLOT(map()), connect(cmd, SIGNAL(success()), m_repositoryChangedSignalMapper, SLOT(map()),
@@ -2339,18 +2154,19 @@ void GitClient::connectRepositoryChanged(const QString & repository, GitCommand
} }
// determine version as '(major << 16) + (minor << 8) + patch' or 0. // determine version as '(major << 16) + (minor << 8) + patch' or 0.
unsigned GitClient::gitVersion(bool silent, QString *errorMessage) unsigned GitClient::gitVersion(bool silent, QString *errorMessage) const
{ {
if (!m_hasCachedGitVersion) { const QString newGitBinary = gitBinaryPath();
if (m_gitVersionForBinary != newGitBinary && !newGitBinary.isEmpty()) {
// Do not execute repeatedly if that fails (due to git // Do not execute repeatedly if that fails (due to git
// not being installed) until settings are changed. // not being installed) until settings are changed.
m_cachedGitVersion = synchronousGitVersion(silent, errorMessage); m_cachedGitVersion = synchronousGitVersion(silent, errorMessage);
m_hasCachedGitVersion = true; m_gitVersionForBinary = newGitBinary;
} }
return m_cachedGitVersion; return m_cachedGitVersion;
} }
QString GitClient::gitVersionString(bool silent, QString *errorMessage) QString GitClient::gitVersionString(bool silent, QString *errorMessage) const
{ {
if (const unsigned version = gitVersion(silent, errorMessage)) { if (const unsigned version = gitVersion(silent, errorMessage)) {
QString rc; QString rc;
@@ -2361,9 +2177,8 @@ QString GitClient::gitVersionString(bool silent, QString *errorMessage)
} }
return QString(); return QString();
} }
// determine version as '(major << 16) + (minor << 8) + patch' or 0. // determine version as '(major << 16) + (minor << 8) + patch' or 0.
unsigned GitClient::synchronousGitVersion(bool silent, QString *errorMessage) unsigned GitClient::synchronousGitVersion(bool silent, QString *errorMessage) const
{ {
// run git --version // run git --version
QByteArray outputText; QByteArray outputText;
+16 -43
View File
@@ -38,6 +38,7 @@
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <QtCore/QObject>
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtGui/QWidget> #include <QtGui/QWidget>
@@ -79,9 +80,13 @@ class GitClient : public QObject
public: public:
static const char *stashNamePrefix; static const char *stashNamePrefix;
explicit GitClient(GitPlugin *plugin); explicit GitClient(GitSettings *settings);
~GitClient(); ~GitClient();
QString gitBinaryPath(bool *ok = 0, QString *errorMessage = 0) const;
unsigned gitVersion(bool silent, QString *errorMessage = 0) const;
QString gitVersionString(bool silent, QString *errorMessage = 0) const;
static QString findRepositoryForDirectory(const QString &dir); static QString findRepositoryForDirectory(const QString &dir);
void diff(const QString &workingDirectory, const QStringList &diffArgs, const QString &fileName); void diff(const QString &workingDirectory, const QStringList &diffArgs, const QString &fileName);
@@ -94,7 +99,7 @@ public:
void status(const QString &workingDirectory); void status(const QString &workingDirectory);
void graphLog(const QString &workingDirectory) { graphLog(workingDirectory, QString()); } void graphLog(const QString &workingDirectory) { graphLog(workingDirectory, QString()); }
void graphLog(const QString &workingDirectory, const QString &branch); void graphLog(const QString &workingDirectory, const QString &branch);
void log(const QString &workingDirectory, const QStringList &fileNames, void log(const QString &workingDirectory, const QStringList &fileNames = QStringList(),
bool enableAnnotationContextMenu = false); bool enableAnnotationContextMenu = false);
void blame(const QString &workingDirectory, const QStringList &args, const QString &fileName, void blame(const QString &workingDirectory, const QStringList &args, const QString &fileName,
const QString &revision = QString(), int lineNumber = -1); const QString &revision = QString(), int lineNumber = -1);
@@ -160,10 +165,6 @@ public:
QStringList *descriptions, QString *errorMessage); QStringList *descriptions, QString *errorMessage);
bool synchronousTopRevision(const QString &workingDirectory, QString *revision = 0, bool synchronousTopRevision(const QString &workingDirectory, QString *revision = 0,
QString *branch = 0, QString *errorMessage = 0); QString *branch = 0, QString *errorMessage = 0);
// determine version as '(major << 16) + (minor << 8) + patch' or 0
// with some smart caching.
unsigned gitVersion(bool silent, QString *errorMessage = 0);
QString gitVersionString(bool silent, QString *errorMessage = 0);
bool cloneRepository(const QString &directory, const QByteArray &url); bool cloneRepository(const QString &directory, const QByteArray &url);
QString vcsGetRepositoryURL(const QString &directory); QString vcsGetRepositoryURL(const QString &directory);
@@ -218,12 +219,9 @@ public:
void launchGitK(const QString &workingDirectory); void launchGitK(const QString &workingDirectory);
QStringList synchronousRepositoryBranches(const QString &repositoryURL); QStringList synchronousRepositoryBranches(const QString &repositoryURL);
GitSettings settings() const; GitSettings *settings() const;
void setSettings(const GitSettings &s);
QString binary() const; // Executable + basic arguments
QProcessEnvironment processEnvironment() const; QProcessEnvironment processEnvironment() const;
static QString fakeWinHome(const QProcessEnvironment &e);
static QString msgNoChangedFiles(); static QString msgNoChangedFiles();
@@ -249,13 +247,13 @@ private:
GitCommand *createCommand(const QString &workingDirectory, GitCommand *createCommand(const QString &workingDirectory,
VCSBase::VCSBaseEditorWidget* editor = 0, VCSBase::VCSBaseEditorWidget* editor = 0,
bool outputToWindow = false, bool useOutputToWindow = false,
int editorLineNumber = -1); int editorLineNumber = -1);
GitCommand *executeGit(const QString &workingDirectory, GitCommand *executeGit(const QString &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
VCSBase::VCSBaseEditorWidget* editor = 0, VCSBase::VCSBaseEditorWidget* editor = 0,
bool outputToWindow = false, bool useOutputToWindow = false,
GitCommand::TerminationReportMode tm = GitCommand::NoReport, GitCommand::TerminationReportMode tm = GitCommand::NoReport,
int editorLineNumber = -1, int editorLineNumber = -1,
bool unixTerminalDisabled = false); bool unixTerminalDisabled = false);
@@ -265,7 +263,7 @@ private:
const QStringList &arguments, const QStringList &arguments,
QByteArray* outputText, QByteArray* outputText,
QByteArray* errorText, QByteArray* errorText,
bool logCommandToWindow = true); bool logCommandToWindow = true) const;
// Synchronous git execution using Utils::SynchronousProcess, with // Synchronous git execution using Utils::SynchronousProcess, with
// log windows updating (using VCSBasePlugin::runVCS with flags). // log windows updating (using VCSBasePlugin::runVCS with flags).
@@ -274,7 +272,7 @@ private:
unsigned flags = 0, QTextCodec *outputCodec = 0); unsigned flags = 0, QTextCodec *outputCodec = 0);
// determine version as '(major << 16) + (minor << 8) + patch' or 0. // determine version as '(major << 16) + (minor << 8) + patch' or 0.
unsigned synchronousGitVersion(bool silent, QString *errorMessage = 0); unsigned synchronousGitVersion(bool silent, QString *errorMessage = 0) const;
enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed }; enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed };
RevertResult revertI(QStringList files, RevertResult revertI(QStringList files,
@@ -289,37 +287,12 @@ private:
const QString &gitBinDirectory, const QString &gitBinDirectory,
bool silent); bool silent);
mutable QString m_gitVersionForBinary;
mutable unsigned m_cachedGitVersion;
const QString m_msgWait; const QString m_msgWait;
GitPlugin *m_plugin; Core::ICore *m_core;
Core::ICore *m_core;
GitSettings m_settings;
QString m_binaryPath;
QSignalMapper *m_repositoryChangedSignalMapper; QSignalMapper *m_repositoryChangedSignalMapper;
unsigned m_cachedGitVersion;
bool m_hasCachedGitVersion;
};
class BaseGitArgumentsWidget : public QWidget {
Q_OBJECT
public:
BaseGitArgumentsWidget(GitSettings *settings,
GitClient *client, const QString &directory,
const QStringList &args);
virtual QStringList arguments() const = 0;
public slots:
virtual void redoCommand() = 0;
protected slots:
virtual void testForArgumentsChanged() = 0;
protected:
GitClient *m_client;
const QString m_workingDirectory;
QStringList m_diffArgs;
GitSettings *m_settings; GitSettings *m_settings;
}; };
+1 -7
View File
@@ -122,11 +122,6 @@ void GitCommand::execute()
QLatin1String("Git.action")); QLatin1String("Git.action"));
} }
QString GitCommand::msgTimeout(int seconds)
{
return tr("Error: Git timed out after %1s.").arg(seconds);
}
void GitCommand::run() void GitCommand::run()
{ {
const unsigned processFlags = m_unixTerminalDisabled ? const unsigned processFlags = m_unixTerminalDisabled ?
@@ -160,7 +155,7 @@ void GitCommand::run()
&stdOut, &stdErr, false)) { &stdOut, &stdErr, false)) {
Utils::SynchronousProcess::stopProcess(*process); Utils::SynchronousProcess::stopProcess(*process);
ok = false; ok = false;
error += msgTimeout(timeOutSeconds); error += tr("Error: Git timed out after %1s.").arg(timeOutSeconds);
break; break;
} }
@@ -233,6 +228,5 @@ QVariant GitCommand::cookie() const
return m_cookie; return m_cookie;
} }
} // namespace Internal } // namespace Internal
} // namespace Git } // namespace Git
-2
View File
@@ -73,8 +73,6 @@ public:
bool unixTerminalDisabled() const; bool unixTerminalDisabled() const;
void setUnixTerminalDisabled(bool); void setUnixTerminalDisabled(bool);
static QString msgTimeout(int seconds);
void setCookie(const QVariant &cookie); void setCookie(const QVariant &cookie);
QVariant cookie() const; QVariant cookie() const;
-1
View File
@@ -57,7 +57,6 @@ const char * const GITSUBMITEDITOR_DISPLAY_NAME = QT_TRANSLATE_NOOP("VCS", "Git
const char * const SUBMIT_CURRENT = "Git.SubmitCurrentLog"; const char * const SUBMIT_CURRENT = "Git.SubmitCurrentLog";
const char * const DIFF_SELECTED = "Git.DiffSelectedFilesInLog"; const char * const DIFF_SELECTED = "Git.DiffSelectedFilesInLog";
const char * const SUBMIT_MIMETYPE = "application/vnd.nokia.text.git.submit"; const char * const SUBMIT_MIMETYPE = "application/vnd.nokia.text.git.submit";
const char * const GIT_BINARY = "git";
} // namespace Constants } // namespace Constants
} // namespace Git } // namespace Git
+1 -1
View File
@@ -197,7 +197,7 @@ void GitEditor::setPlainTextDataFiltered(const QByteArray &a)
QByteArray array = a; QByteArray array = a;
// If desired, filter out the date from annotation // If desired, filter out the date from annotation
const bool omitAnnotationDate = contentType() == VCSBase::AnnotateOutput const bool omitAnnotationDate = contentType() == VCSBase::AnnotateOutput
&& GitPlugin::instance()->settings().omitAnnotationDate; && GitPlugin::instance()->settings().boolValue(GitSettings::omitAnnotationDateKey);
if (omitAnnotationDate) if (omitAnnotationDate)
array = removeAnnotationDate(a); array = removeAnnotationDate(a);
setPlainTextData(array); setPlainTextData(array);
+13 -9
View File
@@ -44,6 +44,7 @@
#include "clonewizard.h" #include "clonewizard.h"
#include "gitoriousclonewizard.h" #include "gitoriousclonewizard.h"
#include "stashdialog.h" #include "stashdialog.h"
#include "settingspage.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@@ -280,7 +281,9 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
Q_UNUSED(errorMessage) Q_UNUSED(errorMessage)
m_core = Core::ICore::instance(); m_core = Core::ICore::instance();
m_gitClient = new GitClient(this); m_settings.readSettings(m_core->settings());
m_gitClient = new GitClient(&m_settings);
typedef VCSBase::VCSEditorFactory<GitEditor> GitEditorFactory; typedef VCSBase::VCSEditorFactory<GitEditor> GitEditorFactory;
typedef VCSBase::VCSSubmitEditorFactory<GitSubmitEditor> GitSubmitEditorFactory; typedef VCSBase::VCSSubmitEditorFactory<GitSubmitEditor> GitSubmitEditorFactory;
@@ -753,13 +756,12 @@ bool GitPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEdi
return true; return true;
// Prompt user. Force a prompt unless submit was actually invoked (that // Prompt user. Force a prompt unless submit was actually invoked (that
// is, the editor was closed or shutdown). // is, the editor was closed or shutdown).
GitSettings settings = m_gitClient->settings(); bool *promptData = m_settings.boolPointer(GitSettings::promptOnSubmitKey);
const bool wantedPrompt = settings.promptToSubmit;
const VCSBase::VCSBaseSubmitEditor::PromptSubmitResult answer = const VCSBase::VCSBaseSubmitEditor::PromptSubmitResult answer =
editor->promptSubmit(tr("Closing Git Editor"), editor->promptSubmit(tr("Closing Git Editor"),
tr("Do you want to commit the change?"), tr("Do you want to commit the change?"),
tr("Git will not accept this commit. Do you want to continue to edit it?"), tr("Git will not accept this commit. Do you want to continue to edit it?"),
&settings.promptToSubmit, !m_submitActionTriggered, false); promptData, !m_submitActionTriggered, false);
m_submitActionTriggered = false; m_submitActionTriggered = false;
switch (answer) { switch (answer) {
case VCSBase::VCSBaseSubmitEditor::SubmitCanceled: case VCSBase::VCSBaseSubmitEditor::SubmitCanceled:
@@ -770,8 +772,6 @@ bool GitPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEdi
default: default:
break; break;
} }
if (wantedPrompt != settings.promptToSubmit)
m_gitClient->setSettings(settings);
// Go ahead! // Go ahead!
const QStringList fileList = editor->checkedFiles(); const QStringList fileList = editor->checkedFiles();
bool closeEditor = true; bool closeEditor = true;
@@ -1059,14 +1059,18 @@ void GitPlugin::showCommit()
m_gitClient->show(m_changeSelectionDialog->repository(), change); m_gitClient->show(m_changeSelectionDialog->repository(), change);
} }
GitSettings GitPlugin::settings() const const GitSettings &GitPlugin::settings() const
{ {
return m_gitClient->settings(); return m_settings;
} }
void GitPlugin::setSettings(const GitSettings &s) void GitPlugin::setSettings(const GitSettings &s)
{ {
m_gitClient->setSettings(s); if (s == m_settings)
return;
m_settings = s;
static_cast<GitVersionControl *>(versionControl())->emitConfigurationChanged();
} }
GitClient *GitPlugin::gitClient() const GitClient *GitPlugin::gitClient() const
+4 -4
View File
@@ -33,7 +33,8 @@
#ifndef GITPLUGIN_H #ifndef GITPLUGIN_H
#define GITPLUGIN_H #define GITPLUGIN_H
#include "settingspage.h" #include "gitsettings.h"
#include "vcsbase/vcsbaseplugin.h" #include "vcsbase/vcsbaseplugin.h"
#include <coreplugin/editormanager/ieditorfactory.h> #include <coreplugin/editormanager/ieditorfactory.h>
@@ -69,13 +70,11 @@ namespace Locator {
namespace Git { namespace Git {
namespace Internal { namespace Internal {
class GitPlugin;
class GitVersionControl; class GitVersionControl;
class GitClient; class GitClient;
class ChangeSelectionDialog; class ChangeSelectionDialog;
class GitSubmitEditor; class GitSubmitEditor;
class CommitData; class CommitData;
class GitSettings;
class StashDialog; class StashDialog;
class BranchDialog; class BranchDialog;
class RemoteDialog; class RemoteDialog;
@@ -99,7 +98,7 @@ public:
GitVersionControl *gitVersionControl() const; GitVersionControl *gitVersionControl() const;
GitSettings settings() const; const GitSettings &settings() const;
void setSettings(const GitSettings &s); void setSettings(const GitSettings &s);
GitClient *gitClient() const; GitClient *gitClient() const;
@@ -213,6 +212,7 @@ private:
QString m_commitAmendSHA1; QString m_commitAmendSHA1;
bool m_submitActionTriggered; bool m_submitActionTriggered;
GitSettings m_settings;
}; };
} // namespace Git } // namespace Git
+53 -103
View File
@@ -31,105 +31,46 @@
**************************************************************************/ **************************************************************************/
#include "gitsettings.h" #include "gitsettings.h"
#include "gitconstants.h"
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <QtCore/QSettings>
#include <QtCore/QTextStream>
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
static const char groupC[] = "Git";
static const char sysEnvKeyC[] = "SysEnv";
static const char pathKeyC[] = "Path";
static const char logCountKeyC[] = "LogCount";
static const char timeoutKeyC[] = "TimeOut";
static const char pullRebaseKeyC[] = "PullRebase";
static const char promptToSubmitKeyC[] = "PromptForSubmit";
static const char omitAnnotationDateKeyC[] = "OmitAnnotationDate";
static const char ignoreSpaceChangesBlameKeyC[] = "SpaceIgnorantBlame";
static const char ignoreSpaceChangesDiffKeyC[] = "SpaceIgnorantDiff";
static const char diffPatienceKeyC[] = "DiffPatience";
static const char winSetHomeEnvironmentKeyC[] = "WinSetHomeEnvironment";
static const char gitkOptionsKeyC[] = "GitKOptions";
static const char showPrettyFormatC[] = "DiffPrettyFormat";
enum {
defaultPullRebase = 0,
defaultLogCount = 100,
#ifdef Q_OS_WIN
defaultTimeOut = 60
#else
defaultTimeOut = 30
#endif
};
namespace Git { namespace Git {
namespace Internal { namespace Internal {
GitSettings::GitSettings() : const QLatin1String GitSettings::adoptPathKey("SysEnv");
adoptPath(false), const QLatin1String GitSettings::pathKey("Path");
logCount(defaultLogCount), const QLatin1String GitSettings::pullRebaseKey("PullRebase");
timeoutSeconds(defaultTimeOut), const QLatin1String GitSettings::omitAnnotationDateKey("OmitAnnotationDate");
pullRebase(bool(defaultPullRebase)), const QLatin1String GitSettings::ignoreSpaceChangesInDiffKey("SpaceIgnorantDiff");
promptToSubmit(true), const QLatin1String GitSettings::ignoreSpaceChangesInBlameKey("SpaceIgnorantBlame");
omitAnnotationDate(false), const QLatin1String GitSettings::diffPatienceKey("DiffPatience");
ignoreSpaceChangesInDiff(false), const QLatin1String GitSettings::winSetHomeEnvironmentKey("WinSetHomeEnvironment");
ignoreSpaceChangesInBlame(true), const QLatin1String GitSettings::showPrettyFormatKey("DiffPrettyFormat");
diffPatience(true), const QLatin1String GitSettings::gitkOptionsKey("GitKOptions");
winSetHomeEnvironment(false),
showPrettyFormat(5)
{
}
void GitSettings::fromSettings(QSettings *settings) GitSettings::GitSettings()
{ {
settings->beginGroup(QLatin1String(groupC)); setSettingsGroup(QLatin1String("Git"));
adoptPath = settings->value(QLatin1String(sysEnvKeyC), false).toBool();
path = settings->value(QLatin1String(pathKeyC), QString()).toString();
logCount = settings->value(QLatin1String(logCountKeyC), defaultLogCount).toInt();
timeoutSeconds = settings->value(QLatin1String(timeoutKeyC), defaultTimeOut).toInt();
pullRebase = settings->value(QLatin1String(pullRebaseKeyC), bool(defaultPullRebase)).toBool();
promptToSubmit = settings->value(QLatin1String(promptToSubmitKeyC), true).toBool();
omitAnnotationDate = settings->value(QLatin1String(omitAnnotationDateKeyC), false).toBool();
ignoreSpaceChangesInDiff = settings->value(QLatin1String(ignoreSpaceChangesDiffKeyC), true).toBool();
ignoreSpaceChangesInBlame = settings->value(QLatin1String(ignoreSpaceChangesBlameKeyC), true).toBool();
diffPatience = settings->value(QLatin1String(diffPatienceKeyC), true).toBool();
winSetHomeEnvironment = settings->value(QLatin1String(winSetHomeEnvironmentKeyC), false).toBool();
gitkOptions = settings->value(QLatin1String(gitkOptionsKeyC)).toString();
showPrettyFormat = settings->value(QLatin1String(showPrettyFormatC), 5).toInt();
settings->endGroup();
}
void GitSettings::toSettings(QSettings *settings) const #ifdef Q_OS_WIN
{ declareKey(binaryPathKey, QLatin1String("git.exe"));
settings->beginGroup(QLatin1String(groupC)); declareKey(timeoutKey, 60);
settings->setValue(QLatin1String(sysEnvKeyC), adoptPath); #else
settings->setValue(QLatin1String(pathKeyC), path); declareKey(binaryPathKey, QLatin1String("git"));
settings->setValue(QLatin1String(logCountKeyC), logCount); declareKey(timeoutKey, 30);
settings->setValue(QLatin1String(timeoutKeyC), timeoutSeconds); #endif
settings->setValue(QLatin1String(pullRebaseKeyC), pullRebase); declareKey(adoptPathKey, false);
settings->setValue(QLatin1String(promptToSubmitKeyC), promptToSubmit); declareKey(pathKey, QString());
settings->setValue(QLatin1String(omitAnnotationDateKeyC), omitAnnotationDate); declareKey(pullRebaseKey, false);
settings->setValue(QLatin1String(ignoreSpaceChangesDiffKeyC), ignoreSpaceChangesInDiff); declareKey(omitAnnotationDateKey, false);
settings->setValue(QLatin1String(ignoreSpaceChangesBlameKeyC), ignoreSpaceChangesInBlame); declareKey(ignoreSpaceChangesInDiffKey, true);
settings->setValue(QLatin1String(diffPatienceKeyC), diffPatience); declareKey(ignoreSpaceChangesInBlameKey, true);
settings->setValue(QLatin1String(winSetHomeEnvironmentKeyC), winSetHomeEnvironment); declareKey(diffPatienceKey, true);
settings->setValue(QLatin1String(gitkOptionsKeyC), gitkOptions); declareKey(winSetHomeEnvironmentKey, false);
settings->setValue(QLatin1String(showPrettyFormatC), showPrettyFormat); declareKey(gitkOptionsKey, QString());
settings->endGroup(); declareKey(showPrettyFormatKey, 5);
}
bool GitSettings::equals(const GitSettings &s) const
{
return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount
&& timeoutSeconds == s.timeoutSeconds && promptToSubmit == s.promptToSubmit
&& pullRebase == s.pullRebase
&& omitAnnotationDate == s.omitAnnotationDate
&& ignoreSpaceChangesInBlame == s.ignoreSpaceChangesInBlame
&& ignoreSpaceChangesInDiff == s.ignoreSpaceChangesInDiff
&& diffPatience == s.diffPatience && winSetHomeEnvironment == s.winSetHomeEnvironment
&& gitkOptions == s.gitkOptions && showPrettyFormat == s.showPrettyFormat;
} }
QString GitSettings::gitBinaryPath(bool *ok, QString *errorMessage) const QString GitSettings::gitBinaryPath(bool *ok, QString *errorMessage) const
@@ -140,22 +81,31 @@ QString GitSettings::gitBinaryPath(bool *ok, QString *errorMessage) const
*ok = true; *ok = true;
if (errorMessage) if (errorMessage)
errorMessage->clear(); errorMessage->clear();
const QString binary = QLatin1String(Constants::GIT_BINARY);
QString currentPath = path; if (m_binaryPath.isEmpty()) {
// Easy, git is assumed to be elsewhere accessible const QString binary = stringValue(binaryPathKey);
if (!adoptPath) QString currentPath = stringValue(pathKey);
currentPath = QString::fromLocal8Bit(qgetenv("PATH")); // Easy, git is assumed to be elsewhere accessible
// Search in path? if (!boolValue(adoptPathKey))
const QString pathBinary = Utils::SynchronousProcess::locateBinary(currentPath, binary); currentPath = QString::fromLocal8Bit(qgetenv("PATH"));
if (pathBinary.isEmpty()) { // Search in path?
if (ok) m_binaryPath = Utils::SynchronousProcess::locateBinary(currentPath, binary);
*ok = false; if (m_binaryPath.isEmpty()) {
if (errorMessage) if (ok)
*errorMessage = QCoreApplication::translate("Git::Internal::GitSettings", *ok = false;
"The binary '%1' could not be located in the path '%2'").arg(binary, path); if (errorMessage)
return binary; *errorMessage = QCoreApplication::translate("Git::Internal::GitSettings",
"The binary '%1' could not be located in the path '%2'")
.arg(binary, currentPath);
}
} }
return pathBinary; return m_binaryPath;
}
GitSettings &GitSettings::operator = (const GitSettings &s)
{
VCSBaseClientSettings::operator =(s);
m_binaryPath.clear();
} }
} // namespace Internal } // namespace Internal
+16 -27
View File
@@ -33,49 +33,38 @@
#ifndef GITSETTINGS_H #ifndef GITSETTINGS_H
#define GITSETTINGS_H #define GITSETTINGS_H
#include <QtCore/QStringList> #include <vcsbase/vcsbaseclientsettings.h>
QT_BEGIN_NAMESPACE #include <QtCore/QStringList>
class QSettings;
QT_END_NAMESPACE
namespace Git { namespace Git {
namespace Internal { namespace Internal {
// Todo: Add user name and password? // Todo: Add user name and password?
class GitSettings class GitSettings : public VCSBase::VCSBaseClientSettings
{ {
public: public:
GitSettings(); GitSettings();
void fromSettings(QSettings *); static const QLatin1String adoptPathKey;
void toSettings(QSettings *) const; static const QLatin1String pathKey;
static const QLatin1String pullRebaseKey;
static const QLatin1String omitAnnotationDateKey;
static const QLatin1String ignoreSpaceChangesInDiffKey;
static const QLatin1String ignoreSpaceChangesInBlameKey;
static const QLatin1String diffPatienceKey;
static const QLatin1String winSetHomeEnvironmentKey;
static const QLatin1String showPrettyFormatKey;
static const QLatin1String gitkOptionsKey;
/** Return the full path to the git executable */
QString gitBinaryPath(bool *ok = 0, QString *errorMessage = 0) const; QString gitBinaryPath(bool *ok = 0, QString *errorMessage = 0) const;
bool equals(const GitSettings &s) const; GitSettings &operator = (const GitSettings &s);
bool adoptPath; private:
QString path; mutable QString m_binaryPath;
int logCount;
int timeoutSeconds;
bool pullRebase;
bool promptToSubmit;
bool omitAnnotationDate;
bool ignoreSpaceChangesInDiff;
bool ignoreSpaceChangesInBlame;
bool diffPatience;
bool winSetHomeEnvironment;
int showPrettyFormat;
QString gitkOptions;
}; };
inline bool operator==(const GitSettings &p1, const GitSettings &p2)
{ return p1.equals(p2); }
inline bool operator!=(const GitSettings &p1, const GitSettings &p2)
{ return !p1.equals(p2); }
} // namespace Internal } // namespace Internal
} // namespace Git } // namespace Git
+1 -1
View File
@@ -65,7 +65,7 @@ QString GitVersionControl::id() const
bool GitVersionControl::isConfigured() const bool GitVersionControl::isConfigured() const
{ {
bool ok = false; bool ok = false;
m_client->settings().gitBinaryPath(&ok); m_client->gitBinaryPath(&ok);
return ok; return ok;
} }
+17 -16
View File
@@ -70,27 +70,28 @@ SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
GitSettings SettingsPageWidget::settings() const GitSettings SettingsPageWidget::settings() const
{ {
GitSettings rc; GitSettings rc;
rc.path = m_ui.pathLineEdit->text(); rc.setValue(GitSettings::pathKey, m_ui.pathLineEdit->text());
rc.adoptPath = m_ui.environmentGroupBox->isChecked() && !rc.path.isEmpty(); rc.setValue(GitSettings::adoptPathKey, m_ui.environmentGroupBox->isChecked()
rc.logCount = m_ui.logCountSpinBox->value(); && !rc.stringValue(GitSettings::pathKey).isEmpty());
rc.timeoutSeconds = m_ui.timeoutSpinBox->value(); rc.setValue(GitSettings::logCountKey, m_ui.logCountSpinBox->value());
rc.pullRebase = m_ui.pullRebaseCheckBox->isChecked(); rc.setValue(GitSettings::timeoutKey, m_ui.timeoutSpinBox->value());
rc.promptToSubmit = m_ui.promptToSubmitCheckBox->isChecked(); rc.setValue(GitSettings::pullRebaseKey, m_ui.pullRebaseCheckBox->isChecked());
rc.winSetHomeEnvironment = m_ui.winHomeCheckBox->isChecked(); rc.setValue(GitSettings::promptOnSubmitKey, m_ui.promptToSubmitCheckBox->isChecked());
rc.gitkOptions = m_ui.gitkOptionsLineEdit->text().trimmed(); rc.setValue(GitSettings::winSetHomeEnvironmentKey, m_ui.winHomeCheckBox->isChecked());
rc.setValue(GitSettings::gitkOptionsKey, m_ui.gitkOptionsLineEdit->text().trimmed());
return rc; return rc;
} }
void SettingsPageWidget::setSettings(const GitSettings &s) void SettingsPageWidget::setSettings(const GitSettings &s)
{ {
m_ui.environmentGroupBox->setChecked(s.adoptPath); m_ui.environmentGroupBox->setChecked(s.boolValue(GitSettings::adoptPathKey));
m_ui.pathLineEdit->setText(s.path); m_ui.pathLineEdit->setText(s.stringValue(GitSettings::pathKey));
m_ui.logCountSpinBox->setValue(s.logCount); m_ui.logCountSpinBox->setValue(s.intValue(GitSettings::logCountKey));
m_ui.timeoutSpinBox->setValue(s.timeoutSeconds); m_ui.timeoutSpinBox->setValue(s.intValue(GitSettings::timeoutKey));
m_ui.pullRebaseCheckBox->setChecked(s.pullRebase); m_ui.pullRebaseCheckBox->setChecked(s.boolValue(GitSettings::pullRebaseKey));
m_ui.promptToSubmitCheckBox->setChecked(s.promptToSubmit); m_ui.promptToSubmitCheckBox->setChecked(s.boolValue(GitSettings::promptOnSubmitKey));
m_ui.winHomeCheckBox->setChecked(s.winSetHomeEnvironment); m_ui.winHomeCheckBox->setChecked(s.boolValue(GitSettings::winSetHomeEnvironmentKey));
m_ui.gitkOptionsLineEdit->setText(s.gitkOptions); m_ui.gitkOptionsLineEdit->setText(s.stringValue(GitSettings::gitkOptionsKey));
} }
void SettingsPageWidget::setSystemPath() void SettingsPageWidget::setSystemPath()
+52 -14
View File
@@ -843,26 +843,25 @@ static Utils::SynchronousProcessResponse
Utils::SynchronousProcessResponse Utils::SynchronousProcessResponse
VCSBasePlugin::runVCS(const QString &workingDir, VCSBasePlugin::runVCS(const QString &workingDir,
const QString &binary, const QString &binary,
const QStringList &arguments, const QStringList &arguments,
int timeOutMS, int timeOutMS,
unsigned flags, unsigned flags,
QTextCodec *outputCodec /* = 0 */) QTextCodec *outputCodec)
{ {
const QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); const QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
return runVCS(workingDir, binary, arguments, timeOutMS, env, return runVCS(workingDir, binary, arguments, timeOutMS, env,
flags, outputCodec); flags, outputCodec);
} }
Utils::SynchronousProcessResponse Utils::SynchronousProcessResponse VCSBasePlugin::runVCS(const QString &workingDir,
VCSBasePlugin::runVCS(const QString &workingDir, const QString &binary,
const QString &binary, const QStringList &arguments,
const QStringList &arguments, int timeOutMS,
int timeOutMS, QProcessEnvironment env,
QProcessEnvironment env, unsigned flags,
unsigned flags, QTextCodec *outputCodec)
QTextCodec *outputCodec /* = 0 */)
{ {
VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
@@ -950,6 +949,45 @@ Utils::SynchronousProcessResponse
return response; return response;
} }
bool VCSBasePlugin::runFullySynchronous(const QString &workingDirectory,
const QString &binary,
const QStringList &arguments,
const QProcessEnvironment &env,
QByteArray* outputText,
QByteArray* errorText,
int timeoutMS,
bool logCommandToWindow)
{
VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
if (logCommandToWindow)
outputWindow->appendCommand(workingDirectory, binary, arguments);
QProcess process;
process.setWorkingDirectory(workingDirectory);
process.setProcessEnvironment(env);
process.start(binary, arguments);
process.closeWriteChannel();
if (!process.waitForStarted()) {
if (errorText) {
const QString msg = QString::fromLatin1("Unable to execute '%1': %2:")
.arg(binary, process.errorString());
*errorText = msg.toLocal8Bit();
}
return false;
}
if (!Utils::SynchronousProcess::readDataFromProcess(process, timeoutMS,
outputText, errorText, true)) {
errorText->append(tr("Error: Executable timed out after %1s.").arg(timeoutMS / 1000).toLocal8Bit());
Utils::SynchronousProcess::stopProcess(process);
return false;
}
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
bool VCSBasePlugin::runPatch(const QByteArray &input, const QString &workingDirectory, bool VCSBasePlugin::runPatch(const QByteArray &input, const QString &workingDirectory,
int strip, bool reverse) int strip, bool reverse)
{ {
+21 -15
View File
@@ -173,22 +173,28 @@ public:
// triggered by file watchers). // triggered by file watchers).
}; };
static Utils::SynchronousProcessResponse static Utils::SynchronousProcessResponse runVCS(const QString &workingDir,
runVCS(const QString &workingDir, const QString &binary,
const QString &binary, const QStringList &arguments,
const QStringList &arguments, int timeOutMS,
int timeOutMS, QProcessEnvironment env,
QProcessEnvironment env, unsigned flags = 0,
unsigned flags = 0, QTextCodec *outputCodec = 0);
QTextCodec *outputCodec = 0);
static Utils::SynchronousProcessResponse static Utils::SynchronousProcessResponse runVCS(const QString &workingDir,
runVCS(const QString &workingDir, const QString &binary,
const QString &binary, const QStringList &arguments,
const QStringList &arguments, int timeOutMS,
int timeOutMS, unsigned flags = 0,
unsigned flags = 0, QTextCodec *outputCodec = 0);
QTextCodec *outputCodec = 0);
// Make sure to not pass through the event loop at all:
static bool runFullySynchronous(const QString &workingDirectory,
const QString &binary,
const QStringList &arguments,
const QProcessEnvironment &env,
QByteArray* outputText,
QByteArray *errorText, int timeoutMS, bool logCommandToWindow);
// Utility to run the 'patch' command // Utility to run the 'patch' command
static bool runPatch(const QByteArray &input, const QString &workingDirectory = QString(), static bool runPatch(const QByteArray &input, const QString &workingDirectory = QString(),