From 4a5af14b7f1260f2a4d2bb7c4bd3883fc5baf524 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh <orgad.shaneh@audiocodes.com> Date: Mon, 2 Dec 2013 23:28:58 +0200 Subject: [PATCH] Git: Enable choosing non-fast-forward merge Change-Id: I5972489d06637616953bd0d93a3b65c4d9918377 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com> Reviewed-by: Tobias Hunger <tobias.hunger@digia.com> Reviewed-by: Petar Perisin <petar.perisin@gmail.com> --- src/plugins/git/branchdialog.cpp | 15 ++++++++++++++- src/plugins/git/gitclient.cpp | 20 +++++++++++++++++--- src/plugins/git/gitclient.h | 4 +++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp index 9fadf16934a..09e21ba2c8f 100644 --- a/src/plugins/git/branchdialog.cpp +++ b/src/plugins/git/branchdialog.cpp @@ -38,11 +38,14 @@ #include "stashdialog.h" // Label helpers #include <utils/qtcassert.h> +#include <utils/execmenu.h> #include <vcsbase/vcsbaseoutputwindow.h> +#include <QAction> #include <QItemSelectionModel> #include <QMessageBox> #include <QList> +#include <QMenu> #include <QDebug> @@ -321,8 +324,18 @@ void BranchDialog::merge() const QString branch = m_model->fullName(idx, true); GitClient *client = GitPlugin::instance()->gitClient(); + bool allowFastForward = true; + if (client->isFastForwardMerge(m_repository, branch)) { + QMenu popup; + QAction *fastForward = popup.addAction(tr("Fast-Forward")); + popup.addAction(tr("No Fast-Forward")); + QAction *chosen = Utils::execMenuAtWidget(&popup, m_ui->mergeButton); + if (!chosen) + return; + allowFastForward = (chosen == fastForward); + } if (client->beginStashScope(m_repository, QLatin1String("merge"), AllowUnstashed)) - client->synchronousMerge(m_repository, branch); + client->synchronousMerge(m_repository, branch, allowFastForward); } void BranchDialog::rebase() diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index ed5124c93ce..6842489a82c 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -2106,6 +2106,17 @@ bool GitClient::isRemoteCommit(const QString &workingDirectory, const QString &c return !outputText.isEmpty(); } +bool GitClient::isFastForwardMerge(const QString &workingDirectory, const QString &branch) +{ + QStringList arguments; + QByteArray outputText; + arguments << QLatin1String("merge-base") << QLatin1String(HEAD) << branch; + fullySynchronousGit(workingDirectory, arguments, &outputText, 0, + VcsBasePlugin::SuppressCommandLogging); + return commandOutputFromLocal8Bit(outputText).trimmed() + == synchronousTopRevision(workingDirectory); +} + // Format an entry in a one-liner for selection list using git log. QString GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision, const QString &format) @@ -3485,12 +3496,15 @@ void GitClient::push(const QString &workingDirectory, const QStringList &pushArg executeGit(workingDirectory, arguments, 0, true); } -bool GitClient::synchronousMerge(const QString &workingDirectory, const QString &branch) +bool GitClient::synchronousMerge(const QString &workingDirectory, const QString &branch, + bool allowFastForward) { QString command = QLatin1String("merge"); - QStringList arguments; + QStringList arguments(command); - arguments << command << branch; + if (!allowFastForward) + arguments << QLatin1String("--no-ff"); + arguments << branch; return executeAndHandleConflicts(workingDirectory, arguments, command); } diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 039d3381b7d..69f11e95539 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -244,13 +244,15 @@ public: QStringList synchronousBranchesForCommit(const QString &workingDirectory, const QString &revision); bool isRemoteCommit(const QString &workingDirectory, const QString &commit); + bool isFastForwardMerge(const QString &workingDirectory, const QString &branch); bool cloneRepository(const QString &directory, const QByteArray &url); QString vcsGetRepositoryURL(const QString &directory); void fetch(const QString &workingDirectory, const QString &remote); bool synchronousPull(const QString &workingDirectory, bool rebase); void push(const QString &workingDirectory, const QStringList &pushArgs = QStringList()); - bool synchronousMerge(const QString &workingDirectory, const QString &branch); + bool synchronousMerge(const QString &workingDirectory, const QString &branch, + bool allowFastForward = true); bool canRebase(const QString &workingDirectory) const; void rebase(const QString &workingDirectory, const QString &baseBranch); bool synchronousRevert(const QString &workingDirectory, const QString &commit); -- GitLab