summaryrefslogtreecommitdiff
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.cpp133
1 files changed, 105 insertions, 28 deletions
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index af2bc36bd1..1b3d521559 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -36,6 +36,8 @@
#include "gitsubmiteditor.h"
#include "gitversioncontrol.h"
#include "mergetool.h"
+#include "branchadddialog.h"
+#include "gerrit/gerritplugin.h"
#include <vcsbase/submitfilemodel.h>
@@ -980,11 +982,9 @@ QString GitClient::findGitDirForRepository(const QString &repositoryDir) const
QString &res = repoDirCache[repositoryDir];
if (!res.isEmpty())
return res;
- QByteArray outputText;
- QStringList arguments;
- arguments << QLatin1String("rev-parse") << QLatin1String("--git-dir");
- fullySynchronousGit(repositoryDir, arguments, &outputText, 0, false);
- res = QString::fromLocal8Bit(outputText.trimmed());
+
+ synchronousRevParseCmd(repositoryDir, QLatin1String("--git-dir"), &res);
+
if (!QDir(res).isAbsolute())
res.prepend(repositoryDir + QLatin1Char('/'));
return res;
@@ -1546,12 +1546,10 @@ bool GitClient::synchronousCheckout(const QString &workingDirectory,
{
QByteArray outputText;
QByteArray errorText;
- QStringList arguments;
- arguments << QLatin1String("checkout") << ref;
+ QStringList arguments = setupCheckoutArguments(workingDirectory, ref);
const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText,
VcsBasePlugin::ExpectRepoChanges);
- const QString output = commandOutputFromLocal8Bit(outputText);
- outputWindow()->append(output);
+ outputWindow()->append(commandOutputFromLocal8Bit(outputText));
if (!rc) {
msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
return false;
@@ -1560,6 +1558,67 @@ bool GitClient::synchronousCheckout(const QString &workingDirectory,
return true;
}
+/* method used to setup arguments for checkout, in case user wants to create local branch */
+QStringList GitClient::setupCheckoutArguments(const QString &workingDirectory,
+ const QString &ref)
+{
+ QStringList arguments(QLatin1String("checkout"));
+ arguments << ref;
+
+ QStringList localBranches = synchronousRepositoryBranches(workingDirectory);
+
+ if (localBranches.contains(ref))
+ return arguments;
+
+ if (QMessageBox::question(Core::ICore::mainWindow(), tr("Create Local Branch"),
+ tr("Would you like to create local branch?"),
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
+ return arguments;
+ }
+
+ if (synchronousCurrentLocalBranch(workingDirectory).isEmpty())
+ localBranches.removeFirst();
+
+ QString refSha;
+ if (!synchronousRevParseCmd(workingDirectory, ref, &refSha))
+ return arguments;
+
+ QString output;
+ QStringList forEachRefArgs(QLatin1String("refs/remotes/"));
+ forEachRefArgs << QLatin1String("--format=%(objectname) %(refname:short)");
+ if (!synchronousForEachRefCmd(workingDirectory, forEachRefArgs, &output))
+ return arguments;
+
+ QString remoteBranch;
+ const QString head(QLatin1String("/HEAD"));
+
+ foreach (const QString &singleRef, output.split(QLatin1Char('\n'))) {
+ if (singleRef.startsWith(refSha)) {
+ // branch name might be origin/foo/HEAD
+ if (!singleRef.endsWith(head) || singleRef.count(QLatin1Char('/')) > 1) {
+ remoteBranch = singleRef.mid(refSha.length() + 1);
+ if (remoteBranch == ref)
+ break;
+ }
+ }
+ }
+
+ BranchAddDialog branchAddDialog(localBranches, true, Core::ICore::mainWindow());
+ branchAddDialog.setTrackedBranchName(remoteBranch, true);
+
+ if (branchAddDialog.exec() != QDialog::Accepted)
+ return arguments;
+
+ arguments.removeLast();
+ arguments << QLatin1String("-b") << branchAddDialog.branchName();
+ if (branchAddDialog.track())
+ arguments << QLatin1String("--track") << remoteBranch;
+ else
+ arguments << QLatin1String("--no-track") << ref;
+
+ return arguments;
+}
+
void GitClient::reset(const QString &workingDirectory, const QString &argument, const QString &commit)
{
QStringList arguments;
@@ -1946,25 +2005,28 @@ QString GitClient::synchronousTopic(const QString &workingDirectory)
return data.topic = remoteBranch.isEmpty() ? tr("Detached HEAD") : remoteBranch;
}
+bool GitClient::synchronousRevParseCmd(const QString &workingDirectory, const QString &ref,
+ QString *output, QString *errorMessage) const
+{
+ QStringList arguments(QLatin1String("rev-parse"));
+ arguments << ref;
+ QByteArray outputText;
+ QByteArray errorText;
+ const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputText, &errorText,
+ VcsBasePlugin::SuppressCommandLogging);
+ *output = commandOutputFromLocal8Bit(outputText.trimmed());
+ if (!rc)
+ msgCannotRun(arguments, workingDirectory, errorText, errorMessage);
+
+ return rc;
+}
+
// Retrieve head revision
QString GitClient::synchronousTopRevision(const QString &workingDirectory, QString *errorMessageIn)
{
- QByteArray outputTextData;
- QByteArray errorText;
- QStringList arguments;
- QString errorMessage;
- // get revision
- arguments << QLatin1String("rev-parse") << QLatin1String(HEAD);
- if (!fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText,
- VcsBasePlugin::SuppressCommandLogging)) {
- errorMessage = tr("Cannot retrieve top revision of \"%1\": %2")
- .arg(QDir::toNativeSeparators(workingDirectory), commandOutputFromLocal8Bit(errorText));
+ QString revision;
+ if (!synchronousRevParseCmd(workingDirectory, QLatin1String(HEAD), &revision, errorMessageIn))
return QString();
- }
- QString revision = commandOutputFromLocal8Bit(outputTextData);
- revision.remove(QLatin1Char('\n'));
- if (revision.isEmpty() && !errorMessage.isEmpty())
- msgCannotRun(errorMessage, errorMessageIn);
return revision;
}
@@ -2458,12 +2520,13 @@ QProcessEnvironment GitClient::processEnvironment() const
return environment;
}
-bool GitClient::beginStashScope(const QString &workingDirectory, const QString &command, StashFlag flag)
+bool GitClient::beginStashScope(const QString &workingDirectory, const QString &command,
+ StashFlag flag, PushAction pushAction)
{
const QString repoDirectory = findRepositoryForDirectory(workingDirectory);
QTC_ASSERT(!repoDirectory.isEmpty(), return false);
StashInfo &stashInfo = m_stashInfo[repoDirectory];
- return stashInfo.init(repoDirectory, command, flag);
+ return stashInfo.init(repoDirectory, command, flag, pushAction);
}
GitClient::StashInfo &GitClient::stashInfo(const QString &workingDirectory)
@@ -2957,6 +3020,11 @@ bool GitClient::getCommitData(const QString &workingDirectory,
commitData.commitEncoding = readConfigValue(workingDirectory, QLatin1String("i18n.commitEncoding"));
+ // Set default commit encoding to 'UTF-8', when it's not set,
+ // to solve displaying error of commit log with non-latin characters.
+ if (commitData.commitEncoding.isEmpty())
+ commitData.commitEncoding = QLatin1String("UTF-8");
+
// Get the commit template or the last commit message
switch (commitData.commitType) {
case AmendCommit: {
@@ -3722,15 +3790,17 @@ unsigned GitClient::synchronousGitVersion(QString *errorMessage) const
}
GitClient::StashInfo::StashInfo() :
- m_client(GitPlugin::instance()->gitClient())
+ m_client(GitPlugin::instance()->gitClient()),
+ m_pushAction(NoPush)
{
}
bool GitClient::StashInfo::init(const QString &workingDirectory, const QString &command,
- StashFlag flag)
+ StashFlag flag, PushAction pushAction)
{
m_workingDir = workingDirectory;
m_flags = flag;
+ m_pushAction = pushAction;
QString errorMessage;
QString statusOutput;
switch (m_client->gitStatus(m_workingDir, StatusMode(NoUntracked | NoSubmodules),
@@ -3829,6 +3899,13 @@ void GitClient::StashInfo::end()
if (m_client->stashNameFromMessage(m_workingDir, m_message, &stashName))
m_client->stashPop(m_workingDir, stashName);
}
+
+ if (m_pushAction == NormalPush)
+ m_client->push(m_workingDir);
+ else if (m_pushAction == PushToGerrit)
+ GitPlugin::instance()->gerritPlugin()->push(m_workingDir);
+
+ m_pushAction = NoPush;
m_stashResult = NotStashed;
}
} // namespace Internal