diff --git a/src/plugins/git/gerrit/gerritplugin.cpp b/src/plugins/git/gerrit/gerritplugin.cpp index d05a22ca8eb..e070f9749a3 100644 --- a/src/plugins/git/gerrit/gerritplugin.cpp +++ b/src/plugins/git/gerrit/gerritplugin.cpp @@ -309,7 +309,7 @@ void FetchContext::cherryPick() // Point user to errors. VcsBase::VcsBaseOutputWindow::instance()->popup(Core::IOutputPane::ModeSwitch | Core::IOutputPane::WithFocus); VcsBase::VcsBaseOutputWindow::instance()->append(tr("Cherry-picking %1...").arg(m_patchFileName)); - Git::Internal::GitPlugin::instance()->gitClient()->cherryPickCommit( + Git::Internal::GitPlugin::instance()->gitClient()->synchronousCherryPick( m_repository, QLatin1String("FETCH_HEAD")); } diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 82ff778431a..3a1de0ebcdf 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1892,24 +1892,47 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory, St return StatusUnchanged; } -void GitClient::continueCommandIfNeeded(const QString &workingDirectory) +GitClient::CommandInProgress GitClient::checkCommandInProgress(const QString &workingDirectory) { QString gitDir = findGitDirForRepository(workingDirectory); - if (QFile::exists(gitDir + QLatin1String("/rebase-apply/rebasing"))) { + if (QFile::exists(gitDir + QLatin1String("/MERGE_HEAD"))) + return Merge; + else if (QFile::exists(gitDir + QLatin1String("/rebase-apply/rebasing"))) + return Rebase; + else if (QFile::exists(gitDir + QLatin1String("/rebase-merge"))) + return RebaseMerge; + else if (QFile::exists(gitDir + QLatin1String("/REVERT_HEAD"))) + return Revert; + else if (QFile::exists(gitDir + QLatin1String("/CHERRY_PICK_HEAD"))) + return CherryPick; + else + return NoCommand; +} + +void GitClient::continueCommandIfNeeded(const QString &workingDirectory) +{ + switch (checkCommandInProgress(workingDirectory)) { + case Rebase: continuePreviousGitCommand(workingDirectory, tr("Continue Rebase"), tr("Continue rebase?"), tr("Continue"), QLatin1String("rebase")); - } else if (QFile::exists(gitDir + QLatin1String("/rebase-merge"))) { + break; + case RebaseMerge: continuePreviousGitCommand(workingDirectory, tr("Continue Rebase"), tr("Continue rebase?"), tr("Continue"), QLatin1String("rebase"), false); - } else if (QFile::exists(gitDir + QLatin1String("/REVERT_HEAD"))) { + break; + case Revert: continuePreviousGitCommand(workingDirectory, tr("Continue Revert"), tr("You need to commit changes to finish revert.\nCommit now?"), tr("Commit"), QLatin1String("revert")); - } else if (QFile::exists(gitDir + QLatin1String("/CHERRY_PICK_HEAD"))) { + break; + case CherryPick: continuePreviousGitCommand(workingDirectory, tr("Continue Cherry-Picking"), tr("You need to commit changes to finish cherry-picking.\nCommit now?"), tr("Commit"), QLatin1String("cherry-pick")); + break; + default: + break; } } @@ -2568,7 +2591,7 @@ bool GitClient::synchronousRebase(const QString &workingDirectory, const QString return executeAndHandleConflicts(workingDirectory, arguments, command); } -bool GitClient::revertCommit(const QString &workingDirectory, const QString &commit) +bool GitClient::synchronousRevert(const QString &workingDirectory, const QString &commit) { QStringList arguments; QString command = QLatin1String("revert"); @@ -2577,7 +2600,7 @@ bool GitClient::revertCommit(const QString &workingDirectory, const QString &com return executeAndHandleConflicts(workingDirectory, arguments, command); } -bool GitClient::cherryPickCommit(const QString &workingDirectory, const QString &commit) +bool GitClient::synchronousCherryPick(const QString &workingDirectory, const QString &commit) { QStringList arguments; QString command = QLatin1String("cherry-pick"); diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 565960ec2d7..32ef837d176 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -90,6 +90,9 @@ public: enum StashResult { StashUnchanged, StashCanceled, StashFailed, Stashed, NotStashed /* User did not want it */ }; + enum CommandInProgress { NoCommand, Revert, CherryPick, + Rebase, Merge, RebaseMerge }; + class StashGuard { public: @@ -232,8 +235,8 @@ public: bool synchronousRebase(const QString &workingDirectory, const QString &baseBranch, const QString &topicBranch = QString()); - bool revertCommit(const QString &workingDirectory, const QString &commit); - bool cherryPickCommit(const QString &workingDirectory, const QString &commit); + bool synchronousRevert(const QString &workingDirectory, const QString &commit); + bool synchronousCherryPick(const QString &workingDirectory, const QString &commit); void interactiveRebase(const QString &workingDirectory, const QString &commit); void synchronousAbortCommand(const QString &workingDir, const QString &abortCommand); @@ -277,6 +280,7 @@ public: QString *output = 0, QString *errorMessage = 0); + CommandInProgress checkCommandInProgress(const QString &workingDirectory); void continueCommandIfNeeded(const QString &workingDirectory); void continuePreviousGitCommand(const QString &workingDirectory, const QString &msgBoxTitle, QString msgBoxText, const QString &buttonName, const QString &gitCommand, bool requireChanges = true); diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 2e37f4e463a..1faa6b58bad 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -213,14 +213,14 @@ void GitEditor::cherryPickChange() { const QFileInfo fi(source()); const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); - GitPlugin::instance()->gitClient()->cherryPickCommit(workingDirectory, m_currentChange); + GitPlugin::instance()->gitClient()->synchronousCherryPick(workingDirectory, m_currentChange); } void GitEditor::revertChange() { const QFileInfo fi(source()); const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath(); - GitPlugin::instance()->gitClient()->revertCommit(workingDirectory, m_currentChange); + GitPlugin::instance()->gitClient()->synchronousRevert(workingDirectory, m_currentChange); } QString GitEditor::decorateVersion(const QString &revision) const diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index ef1053ca415..ce7429076e6 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -442,6 +442,40 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) createRepositoryAction(localRepositoryMenu, tr("Update Submodules"), Core::Id("Git.SubmoduleUpdate"), globalcontext, true, SLOT(updateSubmodules())).first; + m_abortMergeAction = + createRepositoryAction(localRepositoryMenu, + tr("Abort Merge"), Core::Id("Git.MergeAbort"), + globalcontext, true, SLOT(continueOrAbortCommand())).first; + + m_abortRebaseAction = + createRepositoryAction(localRepositoryMenu, + tr("Abort Rebase"), Core::Id("Git.RebaseAbort"), + globalcontext, true, SLOT(continueOrAbortCommand())).first; + + m_abortCherryPickAction = + createRepositoryAction(localRepositoryMenu, + tr("Abort Cherry Pick"), Core::Id("Git.CherryPickAbort"), + globalcontext, true, SLOT(continueOrAbortCommand())).first; + + m_abortRevertAction = + createRepositoryAction(localRepositoryMenu, + tr("Abort Revert"), Core::Id("Git.RevertAbort"), + globalcontext, true, SLOT(continueOrAbortCommand())).first; + + m_continueRebaseAction = + createRepositoryAction(localRepositoryMenu, + tr("Continue Rebase"), Core::Id("Git.RebaseContinue"), + globalcontext, true, SLOT(continueOrAbortCommand())).first; + + m_continueCherryPickAction = + createRepositoryAction(localRepositoryMenu, + tr("Continue Cherry Pick"), Core::Id("Git.CherryPickContinue"), + globalcontext, true, SLOT(continueOrAbortCommand())).first; + + m_continueRevertAction = + createRepositoryAction(localRepositoryMenu, + tr("Continue Revert"), Core::Id("Git.RevertContinue"), + globalcontext, true, SLOT(continueOrAbortCommand())).first; // -------------- localRepositoryMenu->addSeparator(globalcontext); @@ -576,9 +610,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) tr("Repository Browser"), Core::Id("Git.LaunchRepositoryBrowser"), globalcontext, true, &GitClient::launchRepositoryBrowser).first; - createRepositoryAction(gitToolsMenu, - tr("Merge Tool"), Core::Id("Git.MergeTool"), - globalcontext, true, SLOT(startMergeTool())); + m_mergeToolAction = + createRepositoryAction(gitToolsMenu, + tr("Merge Tool"), Core::Id("Git.MergeTool"), + globalcontext, true, SLOT(startMergeTool())).first; /* \"Git Tools" menu */ @@ -756,11 +791,11 @@ void GitPlugin::startChangeRelatedAction() switch (dialog->command()) { case CherryPick: command = QLatin1String("Cherry-pick"); - commandFunction = &GitClient::cherryPickCommit; + commandFunction = &GitClient::synchronousCherryPick; break; case Revert: command = QLatin1String("Revert"); - commandFunction = &GitClient::revertCommit; + commandFunction = &GitClient::synchronousRevert; break; case Checkout: command = QLatin1String("Checkout"); @@ -1025,6 +1060,30 @@ void GitPlugin::startMergeTool() m_gitClient->merge(state.topLevel()); } +void GitPlugin::continueOrAbortCommand() +{ + const VcsBase::VcsBasePluginState state = currentState(); + QTC_ASSERT(state.hasTopLevel(), return); + QObject *action = QObject::sender(); + + if (action == m_abortMergeAction) + m_gitClient->synchronousMerge(state.topLevel(), QLatin1String("--abort")); + else if (action == m_abortRebaseAction) + m_gitClient->synchronousRebase(state.topLevel(), QLatin1String("--abort")); + else if (action == m_abortCherryPickAction) + m_gitClient->synchronousCherryPick(state.topLevel(), QLatin1String("--abort")); + else if (action == m_abortRevertAction) + m_gitClient->synchronousRevert(state.topLevel(), QLatin1String("--abort")); + else if (action == m_continueRebaseAction) + m_gitClient->synchronousRebase(state.topLevel(), QLatin1String("--continue")); + else if (action == m_continueCherryPickAction) + m_gitClient->synchronousCherryPick(state.topLevel(), QLatin1String("--continue")); + else if (action == m_continueRevertAction) + m_gitClient->synchronousRevert(state.topLevel(), QLatin1String("--continue")); + + updateContinueAndAbortCommands(); +} + // Retrieve member function of git client stored as user data of action static inline GitClientMemberFunc memberFunctionFromAction(const QObject *o) { @@ -1239,11 +1298,41 @@ void GitPlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as) repositoryAction->setEnabled(repositoryEnabled); m_submoduleUpdateAction->setVisible(repositoryEnabled && QFile::exists(currentState().topLevel() + QLatin1String("/.gitmodules"))); + + updateContinueAndAbortCommands(); updateRepositoryBrowserAction(); m_gerritPlugin->updateActions(repositoryEnabled); } +void GitPlugin::updateContinueAndAbortCommands() +{ + if (currentState().hasTopLevel()) { + GitClient::CommandInProgress gitCommandInProgress = + m_gitClient->checkCommandInProgress(currentState().topLevel()); + + m_mergeToolAction->setVisible(gitCommandInProgress != GitClient::NoCommand); + m_abortMergeAction->setVisible(gitCommandInProgress == GitClient::Merge); + m_abortCherryPickAction->setVisible(gitCommandInProgress == GitClient::CherryPick); + m_abortRevertAction->setVisible(gitCommandInProgress == GitClient::Revert); + m_abortRebaseAction->setVisible(gitCommandInProgress == GitClient::Rebase + || gitCommandInProgress == GitClient::RebaseMerge); + m_continueCherryPickAction->setVisible(gitCommandInProgress == GitClient::CherryPick); + m_continueRevertAction->setVisible(gitCommandInProgress == GitClient::Revert); + m_continueRebaseAction->setVisible(gitCommandInProgress == GitClient::Rebase + || gitCommandInProgress == GitClient::RebaseMerge); + } else { + m_mergeToolAction->setVisible(false); + m_abortMergeAction->setVisible(false); + m_abortCherryPickAction->setVisible(false); + m_abortRevertAction->setVisible(false); + m_abortRebaseAction->setVisible(false); + m_continueCherryPickAction->setVisible(false); + m_continueRevertAction->setVisible(false); + m_continueRebaseAction->setVisible(false); + } +} + void GitPlugin::updateRepositoryBrowserAction() { const bool repositoryEnabled = currentState().hasTopLevel(); diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 711b81acd7d..9bf2f44bdf4 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -139,6 +139,7 @@ private slots: void pull(); void push(); void startMergeTool(); + void continueOrAbortCommand(); #ifdef WITH_TESTS void testStatusParsing_data(); @@ -187,6 +188,7 @@ private: const Core::Context &context, bool addToLocator, GitClientMemberFunc); + void updateContinueAndAbortCommands(); void updateRepositoryBrowserAction(); bool isCommitEditorOpen() const; Core::IEditor *openSubmitEditor(const QString &fileName, const CommitData &cd, bool amend); @@ -206,7 +208,15 @@ private: QAction *m_redoAction; QAction *m_menuAction; QAction *m_repositoryBrowserAction; + QAction *m_mergeToolAction; QAction *m_submoduleUpdateAction; + QAction *m_abortMergeAction; + QAction *m_abortRebaseAction; + QAction *m_abortCherryPickAction; + QAction *m_abortRevertAction; + QAction *m_continueRebaseAction; + QAction *m_continueCherryPickAction; + QAction *m_continueRevertAction; QVector m_fileActions; QVector m_projectActions;