aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/git/gitclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/git/gitclient.cpp')
-rw-r--r--src/plugins/git/gitclient.cpp255
1 files changed, 139 insertions, 116 deletions
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index e419449fe02..935b56291ff 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -19,7 +19,7 @@
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/vcsmanager.h>
-#include <utils/asynctask.h>
+#include <utils/async.h>
#include <utils/algorithm.h>
#include <utils/checkablemessagebox.h>
#include <utils/commandline.h>
@@ -27,8 +27,8 @@
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/mimeutils.h>
+#include <utils/process.h>
#include <utils/qtcassert.h>
-#include <utils/qtcprocess.h>
#include <utils/temporaryfile.h>
#include <utils/theme/theme.h>
@@ -60,7 +60,7 @@
const char GIT_DIRECTORY[] = ".git";
const char HEAD[] = "HEAD";
const char CHERRY_PICK_HEAD[] = "CHERRY_PICK_HEAD";
-const char BRANCHES_PREFIX[] = "Branches: ";
+[[maybe_unused]] const char BRANCHES_PREFIX[] = "Branches: ";
const char stashNamePrefix[] = "stash@{";
const char noColorOption[] = "--no-color";
const char colorOption[] = "--color=always";
@@ -76,6 +76,7 @@ const char showFormatC[] =
using namespace Core;
using namespace DiffEditor;
+using namespace Tasking;
using namespace Utils;
using namespace VcsBase;
@@ -92,7 +93,7 @@ static QString branchesDisplay(const QString &prefix, QStringList *branches, boo
if (*first)
*first = false;
else
- output += QString(sizeof(BRANCHES_PREFIX) - 1, ' '); // Align
+ output += QString(sizeof(BRANCHES_PREFIX) - 1 /* the \0 */, ' '); // Align
output += prefix + ": ";
// If there are more than 'limit' branches, list limit/2 (first limit/4 and last limit/4)
if (count > limit) {
@@ -165,18 +166,18 @@ GitDiffEditorController::GitDiffEditorController(IDocument *document,
const TreeStorage<QString> diffInputStorage = inputStorage();
- const auto setupDiff = [=](QtcProcess &process) {
+ const auto setupDiff = [=](Process &process) {
process.setCodec(VcsBaseEditor::getCodec(workingDirectory(), {}));
setupCommand(process, {addConfigurationArguments(diffArgs(leftCommit, rightCommit, extraArgs))});
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
};
- const auto onDiffDone = [diffInputStorage](const QtcProcess &process) {
- *diffInputStorage.activeStorage() = process.cleanedStdOut();
+ const auto onDiffDone = [diffInputStorage](const Process &process) {
+ *diffInputStorage = process.cleanedStdOut();
};
const Group root {
Storage(diffInputStorage),
- Process(setupDiff, onDiffDone),
+ ProcessTask(setupDiff, onDiffDone),
postProcessTask()
};
setReloadRecipe(root);
@@ -231,7 +232,7 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin
const TreeStorage<DiffStorage> storage;
const TreeStorage<QString> diffInputStorage = inputStorage();
- const auto setupStaged = [this, stagedFiles](QtcProcess &process) {
+ const auto setupStaged = [this, stagedFiles](Process &process) {
if (stagedFiles.isEmpty())
return TaskAction::StopWithError;
process.setCodec(VcsBaseEditor::getCodec(workingDirectory(), stagedFiles));
@@ -240,11 +241,11 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
return TaskAction::Continue;
};
- const auto onStagedDone = [storage](const QtcProcess &process) {
+ const auto onStagedDone = [storage](const Process &process) {
storage->m_stagedOutput = process.cleanedStdOut();
};
- const auto setupUnstaged = [this, unstagedFiles](QtcProcess &process) {
+ const auto setupUnstaged = [this, unstagedFiles](Process &process) {
if (unstagedFiles.isEmpty())
return TaskAction::StopWithError;
process.setCodec(VcsBaseEditor::getCodec(workingDirectory(), unstagedFiles));
@@ -253,12 +254,12 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
return TaskAction::Continue;
};
- const auto onUnstagedDone = [storage](const QtcProcess &process) {
+ const auto onUnstagedDone = [storage](const Process &process) {
storage->m_unstagedOutput = process.cleanedStdOut();
};
const auto onStagingDone = [storage, diffInputStorage] {
- *diffInputStorage.activeStorage() = storage->m_stagedOutput + storage->m_unstagedOutput;
+ *diffInputStorage = storage->m_stagedOutput + storage->m_unstagedOutput;
};
const Group root {
@@ -267,9 +268,9 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin
Group {
parallel,
continueOnDone,
- Process(setupStaged, onStagedDone),
- Process(setupUnstaged, onUnstagedDone),
- OnGroupDone(onStagingDone)
+ ProcessTask(setupStaged, onStagedDone),
+ ProcessTask(setupUnstaged, onUnstagedDone),
+ onGroupDone(onStagingDone)
},
postProcessTask()
};
@@ -321,13 +322,13 @@ ShowController::ShowController(IDocument *document, const QString &id)
setDescription(desc);
};
- const auto setupDescription = [this, id](QtcProcess &process) {
+ const auto setupDescription = [this, id](Process &process) {
process.setCodec(m_instance->encoding(GitClient::EncodingCommit, workingDirectory()));
setupCommand(process, {"show", "-s", noColorOption, showFormatC, id});
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
setDescription(Tr::tr("Waiting for data..."));
};
- const auto onDescriptionDone = [this, storage, updateDescription](const QtcProcess &process) {
+ const auto onDescriptionDone = [this, storage, updateDescription](const Process &process) {
ReloadStorage *data = storage.activeStorage();
const QString output = process.cleanedStdOut();
data->m_postProcessDescription = output.startsWith("commit ");
@@ -348,12 +349,12 @@ ShowController::ShowController(IDocument *document, const QString &id)
return TaskAction::Continue;
};
- const auto setupBranches = [this, storage](QtcProcess &process) {
+ const auto setupBranches = [this, storage](Process &process) {
storage->m_branches = busyMessage;
setupCommand(process, {"branch", noColorOption, "-a", "--contains", storage->m_commit});
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
};
- const auto onBranchesDone = [storage, updateDescription](const QtcProcess &process) {
+ const auto onBranchesDone = [storage, updateDescription](const Process &process) {
ReloadStorage *data = storage.activeStorage();
data->m_branches.clear();
const QString remotePrefix = "remotes/";
@@ -391,17 +392,17 @@ ShowController::ShowController(IDocument *document, const QString &id)
data->m_branches = data->m_branches.trimmed();
updateDescription(*data);
};
- const auto onBranchesError = [storage, updateDescription](const QtcProcess &) {
+ const auto onBranchesError = [storage, updateDescription](const Process &) {
ReloadStorage *data = storage.activeStorage();
data->m_branches.clear();
updateDescription(*data);
};
- const auto setupPrecedes = [this, storage](QtcProcess &process) {
+ const auto setupPrecedes = [this, storage](Process &process) {
storage->m_precedes = busyMessage;
setupCommand(process, {"describe", "--contains", storage->m_commit});
};
- const auto onPrecedesDone = [storage, updateDescription](const QtcProcess &process) {
+ const auto onPrecedesDone = [storage, updateDescription](const Process &process) {
ReloadStorage *data = storage.activeStorage();
data->m_precedes = process.cleanedStdOut().trimmed();
const int tilde = data->m_precedes.indexOf('~');
@@ -411,7 +412,7 @@ ShowController::ShowController(IDocument *document, const QString &id)
data->m_precedes.chop(2);
updateDescription(*data);
};
- const auto onPrecedesError = [storage, updateDescription](const QtcProcess &) {
+ const auto onPrecedesError = [storage, updateDescription](const Process &) {
ReloadStorage *data = storage.activeStorage();
data->m_precedes.clear();
updateDescription(*data);
@@ -427,10 +428,10 @@ ShowController::ShowController(IDocument *document, const QString &id)
data->m_follows = {busyMessage};
data->m_follows.resize(parents.size());
- const auto setupFollow = [this](QtcProcess &process, const QString &parent) {
+ const auto setupFollow = [this](Process &process, const QString &parent) {
setupCommand(process, {"describe", "--tags", "--abbrev=0", parent});
};
- const auto onFollowDone = [data, updateDescription](const QtcProcess &process, int index) {
+ const auto onFollowDone = [data, updateDescription](const Process &process, int index) {
data->m_follows[index] = process.cleanedStdOut().trimmed();
updateDescription(*data);
};
@@ -440,43 +441,43 @@ ShowController::ShowController(IDocument *document, const QString &id)
};
using namespace std::placeholders;
- QList<TaskItem> tasks {parallel, continueOnDone, OnGroupError(onFollowsError)};
+ QList<TaskItem> tasks {parallel, continueOnDone, onGroupError(onFollowsError)};
for (int i = 0, total = parents.size(); i < total; ++i) {
- tasks.append(Process(std::bind(setupFollow, _1, parents.at(i)),
+ tasks.append(ProcessTask(std::bind(setupFollow, _1, parents.at(i)),
std::bind(onFollowDone, _1, i)));
}
taskTree.setupRoot(tasks);
};
- const auto setupDiff = [this, id](QtcProcess &process) {
+ const auto setupDiff = [this, id](Process &process) {
setupCommand(process, addConfigurationArguments(
{"show", "--format=format:", // omit header, already generated
noColorOption, decorateOption, id}));
VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine());
};
- const auto onDiffDone = [diffInputStorage](const QtcProcess &process) {
- *diffInputStorage.activeStorage() = process.cleanedStdOut();
+ const auto onDiffDone = [diffInputStorage](const Process &process) {
+ *diffInputStorage = process.cleanedStdOut();
};
const Group root {
Storage(storage),
Storage(diffInputStorage),
parallel,
- OnGroupSetup([this] { setStartupFile(VcsBase::source(this->document()).toString()); }),
+ onGroupSetup([this] { setStartupFile(VcsBase::source(this->document()).toString()); }),
Group {
- optional,
- Process(setupDescription, onDescriptionDone),
+ finishAllAndDone,
+ ProcessTask(setupDescription, onDescriptionDone),
Group {
parallel,
- optional,
- OnGroupSetup(desciptionDetailsSetup),
- Process(setupBranches, onBranchesDone, onBranchesError),
- Process(setupPrecedes, onPrecedesDone, onPrecedesError),
- Tree(setupFollows)
+ finishAllAndDone,
+ onGroupSetup(desciptionDetailsSetup),
+ ProcessTask(setupBranches, onBranchesDone, onBranchesError),
+ ProcessTask(setupPrecedes, onPrecedesDone, onPrecedesError),
+ TaskTreeTask(setupFollows)
}
},
Group {
- Process(setupDiff, onDiffDone),
+ ProcessTask(setupDiff, onDiffDone),
postProcessTask()
}
};
@@ -490,16 +491,16 @@ class BaseGitDiffArgumentsWidget : public VcsBaseEditorConfig
Q_OBJECT
public:
- BaseGitDiffArgumentsWidget(GitSettings &settings, QToolBar *toolBar) :
- VcsBaseEditorConfig(toolBar)
+ explicit BaseGitDiffArgumentsWidget(QToolBar *toolBar)
+ : VcsBaseEditorConfig(toolBar)
{
m_patienceButton
= addToggleButton("--patience", Tr::tr("Patience"),
Tr::tr("Use the patience algorithm for calculating the differences."));
- mapSetting(m_patienceButton, &settings.diffPatience);
+ mapSetting(m_patienceButton, &settings().diffPatience);
m_ignoreWSButton = addToggleButton("--ignore-space-change", Tr::tr("Ignore Whitespace"),
Tr::tr("Ignore whitespace only changes."));
- mapSetting(m_ignoreWSButton, &settings.ignoreSpaceChangesInDiff);
+ mapSetting(m_ignoreWSButton, &settings().ignoreSpaceChangesInDiff);
}
protected:
@@ -512,15 +513,15 @@ class GitBlameArgumentsWidget : public VcsBaseEditorConfig
Q_OBJECT
public:
- GitBlameArgumentsWidget(GitSettings &settings, QToolBar *toolBar) :
- VcsBaseEditorConfig(toolBar)
+ explicit GitBlameArgumentsWidget(QToolBar *toolBar)
+ : VcsBaseEditorConfig(toolBar)
{
mapSetting(addToggleButton(QString(), Tr::tr("Omit Date"),
Tr::tr("Hide the date of a change from the output.")),
- &settings.omitAnnotationDate);
+ &settings().omitAnnotationDate);
mapSetting(addToggleButton("-w", Tr::tr("Ignore Whitespace"),
Tr::tr("Ignore whitespace only changes.")),
- &settings.ignoreSpaceChangesInBlame);
+ &settings().ignoreSpaceChangesInBlame);
const QList<ChoiceItem> logChoices = {
ChoiceItem(Tr::tr("No Move Detection"), ""),
@@ -529,7 +530,7 @@ public:
ChoiceItem(Tr::tr("Detect Moves and Copies Between Files"), "-M -C -C")
};
mapSetting(addChoices(Tr::tr("Move detection"), {}, logChoices),
- &settings.blameMoveDetection);
+ &settings().blameMoveDetection);
addReloadButton();
}
@@ -540,13 +541,13 @@ class BaseGitLogArgumentsWidget : public BaseGitDiffArgumentsWidget
Q_OBJECT
public:
- BaseGitLogArgumentsWidget(GitSettings &settings, GitEditorWidget *editor) :
- BaseGitDiffArgumentsWidget(settings, editor->toolBar())
+ BaseGitLogArgumentsWidget(GitEditorWidget *editor)
+ : BaseGitDiffArgumentsWidget(editor->toolBar())
{
QToolBar *toolBar = editor->toolBar();
QAction *diffButton = addToggleButton(patchOption, Tr::tr("Diff"),
Tr::tr("Show difference."));
- mapSetting(diffButton, &settings.logDiff);
+ mapSetting(diffButton, &settings().logDiff);
connect(diffButton, &QAction::toggled, m_patienceButton, &QAction::setVisible);
connect(diffButton, &QAction::toggled, m_ignoreWSButton, &QAction::setVisible);
m_patienceButton->setVisible(diffButton->isChecked());
@@ -581,27 +582,27 @@ class GitLogArgumentsWidget : public BaseGitLogArgumentsWidget
Q_OBJECT
public:
- GitLogArgumentsWidget(GitSettings &settings, bool fileRelated, GitEditorWidget *editor) :
- BaseGitLogArgumentsWidget(settings, editor)
+ GitLogArgumentsWidget(bool fileRelated, GitEditorWidget *editor)
+ : BaseGitLogArgumentsWidget(editor)
{
QAction *firstParentButton =
addToggleButton({"-m", "--first-parent"},
Tr::tr("First Parent"),
Tr::tr("Follow only the first parent on merge commits."));
- mapSetting(firstParentButton, &settings.firstParent);
+ mapSetting(firstParentButton, &settings().firstParent);
QAction *graphButton = addToggleButton(graphArguments(), Tr::tr("Graph"),
Tr::tr("Show textual graph log."));
- mapSetting(graphButton, &settings.graphLog);
+ mapSetting(graphButton, &settings().graphLog);
QAction *colorButton = addToggleButton(QStringList{colorOption},
Tr::tr("Color"), Tr::tr("Use colors in log."));
- mapSetting(colorButton, &settings.colorLog);
+ mapSetting(colorButton, &settings().colorLog);
if (fileRelated) {
QAction *followButton = addToggleButton(
"--follow", Tr::tr("Follow"),
Tr::tr("Show log also for previous names of the file."));
- mapSetting(followButton, &settings.followRenames);
+ mapSetting(followButton, &settings().followRenames);
}
addReloadButton();
@@ -640,14 +641,14 @@ class GitRefLogArgumentsWidget : public BaseGitLogArgumentsWidget
Q_OBJECT
public:
- GitRefLogArgumentsWidget(GitSettings &settings, GitEditorWidget *editor) :
- BaseGitLogArgumentsWidget(settings, editor)
+ explicit GitRefLogArgumentsWidget(GitEditorWidget *editor)
+ : BaseGitLogArgumentsWidget(editor)
{
QAction *showDateButton =
addToggleButton("--date=iso",
Tr::tr("Show Date"),
Tr::tr("Show date instead of sequence."));
- mapSetting(showDateButton, &settings.refLogShowDate);
+ mapSetting(showDateButton, &settings().refLogShowDate);
addReloadButton();
}
@@ -735,8 +736,8 @@ static inline void msgCannotRun(const QStringList &args, const FilePath &working
// ---------------- GitClient
-GitClient::GitClient(GitSettings *settings)
- : VcsBase::VcsBaseClientImpl(settings)
+GitClient::GitClient()
+ : VcsBase::VcsBaseClientImpl(&Internal::settings())
{
m_instance = this;
m_gitQtcEditor = QString::fromLatin1("\"%1\" -client -block -pid %2")
@@ -751,7 +752,7 @@ GitClient *GitClient::instance()
GitSettings &GitClient::settings()
{
- return static_cast<GitSettings &>(m_instance->VcsBaseClientImpl::settings());
+ return Internal::settings();
}
FilePath GitClient::findRepositoryForDirectory(const FilePath &directory) const
@@ -821,14 +822,19 @@ FilePaths GitClient::unmanagedFiles(const FilePaths &filePaths) const
return res;
}
+QTextCodec *GitClient::defaultCommitEncoding() const
+{
+ // Set default commit encoding to 'UTF-8', when it's not set,
+ // to solve displaying error of commit log with non-latin characters.
+ return QTextCodec::codecForName("UTF-8");
+}
+
QTextCodec *GitClient::encoding(GitClient::EncodingType encodingType, const FilePath &source) const
{
auto codec = [this](const FilePath &workingDirectory, const QString &configVar) {
const QString codecName = readConfigValue(workingDirectory, configVar).trimmed();
- // Set default commit encoding to 'UTF-8', when it's not set,
- // to solve displaying error of commit log with non-latin characters.
if (codecName.isEmpty())
- return QTextCodec::codecForName("UTF-8");
+ return defaultCommitEncoding();
return QTextCodec::codecForName(codecName.toUtf8());
};
@@ -1074,7 +1080,7 @@ void GitClient::log(const FilePath &workingDirectory, const QString &fileName,
encoding(EncodingLogOutput), "logTitle", msgArg));
VcsBaseEditorConfig *argWidget = editor->editorConfig();
if (!argWidget) {
- argWidget = new GitLogArgumentsWidget(settings(), !fileName.isEmpty(), editor);
+ argWidget = new GitLogArgumentsWidget(!fileName.isEmpty(), editor);
argWidget->setBaseArguments(args);
connect(argWidget, &VcsBaseEditorConfig::commandExecutionRequested, this,
[=] { this->log(workingDir, fileName, enableAnnotationContextMenu, args); });
@@ -1084,7 +1090,7 @@ void GitClient::log(const FilePath &workingDirectory, const QString &fileName,
editor->setWorkingDirectory(workingDir);
QStringList arguments = {"log", decorateOption};
- int logCount = settings().logCount.value();
+ int logCount = settings().logCount();
if (logCount > 0)
arguments << "-n" << QString::number(logCount);
@@ -1130,7 +1136,7 @@ void GitClient::reflog(const FilePath &workingDirectory, const QString &ref)
"reflogRepository", workingDir.toString()));
VcsBaseEditorConfig *argWidget = editor->editorConfig();
if (!argWidget) {
- argWidget = new GitRefLogArgumentsWidget(settings(), editor);
+ argWidget = new GitRefLogArgumentsWidget(editor);
if (!ref.isEmpty())
argWidget->setBaseArguments({ref});
connect(argWidget, &VcsBaseEditorConfig::commandExecutionRequested, this,
@@ -1141,7 +1147,7 @@ void GitClient::reflog(const FilePath &workingDirectory, const QString &ref)
QStringList arguments = {"reflog", noColorOption, decorateOption};
arguments << argWidget->arguments();
- int logCount = settings().logCount.value();
+ int logCount = settings().logCount();
if (logCount > 0)
arguments << "-n" << QString::number(logCount);
@@ -1242,7 +1248,7 @@ void GitClient::annotate(const Utils::FilePath &workingDir, const QString &file,
encoding(EncodingSource, sourceFile), "blameFileName", id);
VcsBaseEditorConfig *argWidget = editor->editorConfig();
if (!argWidget) {
- argWidget = new GitBlameArgumentsWidget(settings(), editor->toolBar());
+ argWidget = new GitBlameArgumentsWidget(editor->toolBar());
argWidget->setBaseArguments(extraOptions);
connect(argWidget, &VcsBaseEditorConfig::commandExecutionRequested, this, [=] {
const int line = VcsBaseEditor::lineNumberOfCurrentEditor();
@@ -1292,14 +1298,15 @@ QStringList GitClient::setupCheckoutArguments(const FilePath &workingDirectory,
if (localBranches.contains(ref))
return arguments;
- if (Utils::CheckableMessageBox::doNotAskAgainQuestion(
- ICore::dialogParent() /*parent*/,
- Tr::tr("Create Local Branch") /*title*/,
- Tr::tr("Would you like to create a local branch?") /*message*/,
- ICore::settings(), "Git.CreateLocalBranchOnCheckout" /*setting*/,
- QDialogButtonBox::Yes | QDialogButtonBox::No /*buttons*/,
- QDialogButtonBox::No /*default button*/,
- QDialogButtonBox::No /*button to save*/) != QDialogButtonBox::Yes) {
+ if (Utils::CheckableMessageBox::question(
+ ICore::dialogParent() /*parent*/,
+ Tr::tr("Create Local Branch") /*title*/,
+ Tr::tr("Would you like to create a local branch?") /*message*/,
+ QString("Git.CreateLocalBranchOnCheckout"), /* decider */
+ QMessageBox::Yes | QMessageBox::No /*buttons*/,
+ QMessageBox::No /*default button*/,
+ QMessageBox::No /*button to save*/)
+ != QMessageBox::Yes) {
return arguments;
}
@@ -1730,19 +1737,25 @@ bool GitClient::synchronousRevParseCmd(const FilePath &workingDirectory, const Q
}
// Retrieve head revision
-QString GitClient::synchronousTopRevision(const FilePath &workingDirectory, QDateTime *dateTime)
+ProcessTask GitClient::topRevision(const FilePath &workingDirectory,
+ const std::function<void(const QString &, const QDateTime &)> &callback)
{
- const QStringList arguments = {"show", "-s", "--pretty=format:%H:%ct", HEAD};
- const CommandResult result = vcsSynchronousExec(workingDirectory, arguments, RunFlags::NoOutput);
- if (result.result() != ProcessResult::FinishedWithSuccess)
- return QString();
- const QStringList output = result.cleanedStdOut().trimmed().split(':');
- if (dateTime && output.size() > 1) {
- bool ok = false;
- const qint64 timeT = output.at(1).toLongLong(&ok);
- *dateTime = ok ? QDateTime::fromSecsSinceEpoch(timeT) : QDateTime();
- }
- return output.first();
+ const auto setupProcess = [=](Process &process) {
+ setupCommand(process, workingDirectory, {"show", "-s", "--pretty=format:%H:%ct", HEAD});
+ };
+ const auto onProcessDone = [=](const Process &process) {
+ const QStringList output = process.cleanedStdOut().trimmed().split(':');
+ QDateTime dateTime;
+ if (output.size() > 1) {
+ bool ok = false;
+ const qint64 timeT = output.at(1).toLongLong(&ok);
+ if (ok)
+ dateTime = QDateTime::fromSecsSinceEpoch(timeT);
+ }
+ callback(output.first(), dateTime);
+ };
+
+ return ProcessTask(setupProcess, onProcessDone);
}
bool GitClient::isRemoteCommit(const FilePath &workingDirectory, const QString &commit)
@@ -1752,13 +1765,6 @@ bool GitClient::isRemoteCommit(const FilePath &workingDirectory, const QString &
return !result.rawStdOut().isEmpty();
}
-bool GitClient::isFastForwardMerge(const FilePath &workingDirectory, const QString &branch)
-{
- const CommandResult result = vcsSynchronousExec(workingDirectory,
- {"merge-base", HEAD, branch}, RunFlags::NoOutput);
- return result.cleanedStdOut().trimmed() == synchronousTopRevision(workingDirectory);
-}
-
// Format an entry in a one-liner for selection list using git log.
QString GitClient::synchronousShortDescription(const FilePath &workingDirectory, const QString &revision,
const QString &format) const
@@ -2420,9 +2426,9 @@ void GitClient::launchGitK(const FilePath &workingDirectory, const QString &file
void GitClient::launchRepositoryBrowser(const FilePath &workingDirectory) const
{
- const FilePath repBrowserBinary = settings().repositoryBrowserCmd.filePath();
+ const FilePath repBrowserBinary = settings().repositoryBrowserCmd();
if (!repBrowserBinary.isEmpty())
- QtcProcess::startDetached({repBrowserBinary, {workingDirectory.toString()}}, workingDirectory);
+ Process::startDetached({repBrowserBinary, {workingDirectory.toString()}}, workingDirectory);
}
static FilePath gitBinDir(const GitClient::GitKLaunchTrial trial, const FilePath &parentDir)
@@ -2466,21 +2472,21 @@ void GitClient::tryLaunchingGitK(const Environment &env,
arguments << "--" << fileName;
VcsOutputWindow::appendCommand(workingDirectory, {binary, arguments});
- // This should always use QtcProcess::startDetached (as not to kill
+ // This should always use Process::startDetached (as not to kill
// the child), but that does not have an environment parameter.
if (!settings().path.value().isEmpty()) {
- auto process = new QtcProcess(const_cast<GitClient*>(this));
+ auto process = new Process(const_cast<GitClient*>(this));
process->setWorkingDirectory(workingDirectory);
process->setEnvironment(env);
process->setCommand({binary, arguments});
- connect(process, &QtcProcess::done, this, [=] {
+ connect(process, &Process::done, this, [=] {
if (process->result() == ProcessResult::StartFailed)
handleGitKFailedToStart(env, workingDirectory, fileName, trial, gitBinDirectory);
process->deleteLater();
});
process->start();
} else {
- if (!QtcProcess::startDetached({binary, arguments}, workingDirectory))
+ if (!Process::startDetached({binary, arguments}, workingDirectory))
handleGitKFailedToStart(env, workingDirectory, fileName, trial, gitBinDirectory);
}
}
@@ -2517,7 +2523,7 @@ bool GitClient::launchGitGui(const FilePath &workingDirectory) {
if (gitBinary.isEmpty()) {
success = false;
} else {
- success = QtcProcess::startDetached({gitBinary, {"gui"}}, workingDirectory);
+ success = Process::startDetached({gitBinary, {"gui"}}, workingDirectory);
}
if (!success)
@@ -2562,7 +2568,7 @@ bool GitClient::launchGitBash(const FilePath &workingDirectory)
success = false;
} else {
const FilePath gitBash = git.absolutePath().parentDir() / "git-bash.exe";
- success = QtcProcess::startDetached({gitBash, {}}, workingDirectory);
+ success = Process::startDetached({gitBash, {}}, workingDirectory);
}
if (!success)
@@ -2574,7 +2580,7 @@ bool GitClient::launchGitBash(const FilePath &workingDirectory)
FilePath GitClient::vcsBinary() const
{
bool ok;
- Utils::FilePath binary = static_cast<GitSettings &>(settings()).gitExecutable(&ok);
+ Utils::FilePath binary = settings().gitExecutable(&ok);
if (!ok)
return Utils::FilePath();
return binary;
@@ -2617,11 +2623,10 @@ bool GitClient::readDataFromCommit(const FilePath &repoDirectory, const QString
return true;
}
-Author GitClient::getAuthor(const Utils::FilePath &workingDirectory)
+Author GitClient::parseAuthor(const QString &authorInfo)
{
// The format is:
// Joe Developer <joedev@example.com> unixtimestamp +HHMM
- const QString authorInfo = readGitVar(workingDirectory, "GIT_AUTHOR_IDENT");
int lt = authorInfo.lastIndexOf('<');
int gt = authorInfo.lastIndexOf('>');
if (gt == -1 || uint(lt) > uint(gt)) {
@@ -2633,6 +2638,12 @@ Author GitClient::getAuthor(const Utils::FilePath &workingDirectory)
return result;
}
+Author GitClient::getAuthor(const Utils::FilePath &workingDirectory)
+{
+ const QString authorInfo = readGitVar(workingDirectory, "GIT_AUTHOR_IDENT");
+ return parseAuthor(authorInfo);
+}
+
bool GitClient::getCommitData(const FilePath &workingDirectory,
QString *commitTemplate,
CommitData &commitData,
@@ -2862,7 +2873,7 @@ bool GitClient::addAndCommit(const FilePath &repositoryDirectory,
GitPlugin::updateCurrentBranch();
return true;
}
- VcsOutputWindow::appendError(Tr::tr("Cannot commit %n files", nullptr, commitCount) + "\n");
+ VcsOutputWindow::appendError(Tr::tr("Cannot commit %n file(s)", nullptr, commitCount) + "\n");
return false;
}
@@ -3120,7 +3131,7 @@ void GitClient::synchronousSubversionFetch(const FilePath &workingDirectory) con
void GitClient::subversionLog(const FilePath &workingDirectory) const
{
QStringList arguments = {"svn", "log"};
- int logCount = settings().logCount.value();
+ int logCount = settings().logCount();
if (logCount > 0)
arguments << ("--limit=" + QString::number(logCount));
@@ -3424,21 +3435,33 @@ QString GitClient::readGitVar(const FilePath &workingDirectory, const QString &c
return readOneLine(workingDirectory, {"var", configVar});
}
-QString GitClient::readOneLine(const FilePath &workingDirectory, const QStringList &arguments) const
+static QTextCodec *configFileCodec()
{
// Git for Windows always uses UTF-8 for configuration:
// https://github.com/msysgit/msysgit/wiki/Git-for-Windows-Unicode-Support#convert-config-files
static QTextCodec *codec = HostOsInfo::isWindowsHost()
? QTextCodec::codecForName("UTF-8")
: QTextCodec::codecForLocale();
+ return codec;
+}
+QString GitClient::readOneLine(const FilePath &workingDirectory, const QStringList &arguments) const
+{
const CommandResult result = vcsSynchronousExec(workingDirectory, arguments,
- RunFlags::NoOutput, vcsTimeoutS(), codec);
+ RunFlags::NoOutput, vcsTimeoutS(),
+ configFileCodec());
if (result.result() == ProcessResult::FinishedWithSuccess)
return result.cleanedStdOut().trimmed();
return {};
}
+void GitClient::readConfigAsync(const FilePath &workingDirectory, const QStringList &arguments,
+ const CommandHandler &handler) const
+{
+ vcsExecWithHandler(workingDirectory, arguments, this, handler, RunFlags::NoOutput,
+ configFileCodec());
+}
+
static unsigned parseGitVersion(const QString &output)
{
// cut 'git version 1.6.5.1.sha'
@@ -3464,8 +3487,8 @@ QFuture<unsigned> GitClient::gitVersion() const
const FilePath newGitBinary = vcsBinary();
const bool needToRunGit = m_gitVersionForBinary != newGitBinary && !newGitBinary.isEmpty();
if (needToRunGit) {
- auto proc = new QtcProcess(const_cast<GitClient *>(this));
- connect(proc, &QtcProcess::done, this, [this, proc, fi, newGitBinary]() mutable {
+ auto proc = new Process(const_cast<GitClient *>(this));
+ connect(proc, &Process::done, this, [this, proc, fi, newGitBinary]() mutable {
if (proc->result() == ProcessResult::FinishedWithSuccess) {
m_cachedGitVersion = parseGitVersion(proc->cleanedStdOut());
m_gitVersionForBinary = newGitBinary;