diff options
Diffstat (limited to 'src/plugins/git/gitclient.cpp')
-rw-r--r-- | src/plugins/git/gitclient.cpp | 133 |
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 |