diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 335a85068c0786be5ece84acb01991274c669245..9f9a646ea11d7120cb196ed5471280e904eb2681 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -584,18 +584,22 @@ bool GitClient::synchronousInit(const QString &workingDirectory) bool GitClient::synchronousCheckoutFiles(const QString &workingDirectory, QStringList files /* = QStringList() */, QString revision /* = QString() */, - QString *errorMessage /* = 0 */) + QString *errorMessage /* = 0 */, + bool revertStaging /* = true */) { if (Git::Constants::debug) qDebug() << Q_FUNC_INFO << workingDirectory << files; - if (revision.isEmpty()) + if (revertStaging && revision.isEmpty()) revision = QLatin1String("HEAD"); if (files.isEmpty()) files = QStringList(QString(QLatin1Char('.'))); QByteArray outputText; QByteArray errorText; QStringList arguments; - arguments << QLatin1String("checkout") << revision << QLatin1String("--") << files; + arguments << QLatin1String("checkout"); + if (revertStaging) + arguments << revision; + arguments << QLatin1String("--") << files; const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText); if (!rc) { const QString fileArg = files.join(QLatin1String(", ")); @@ -1392,7 +1396,10 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory, * reverting a directory pending a sophisticated selection dialog in the * VCSBase plugin. */ -GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirectory, QString *errorMessage) +GitClient::RevertResult GitClient::revertI(QStringList files, + bool *ptrToIsDirectory, + QString *errorMessage, + bool revertStaging) { if (Git::Constants::debug) qDebug() << Q_FUNC_INFO << files; @@ -1454,7 +1461,7 @@ GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirec if (Git::Constants::debug) qDebug() << Q_FUNC_INFO << data.stagedFiles << data.unstagedFiles << allStagedFiles << allUnstagedFiles << stagedFiles << unstagedFiles; - if (stagedFiles.empty() && unstagedFiles.empty()) + if ((!revertStaging || stagedFiles.empty()) && unstagedFiles.empty()) return RevertUnchanged; // Ask to revert (to do: Handle lists with a selection dialog) @@ -1468,19 +1475,22 @@ GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirec return RevertCanceled; // Unstage the staged files - if (!stagedFiles.empty() && !synchronousReset(repoDirectory, stagedFiles, errorMessage)) + if (revertStaging && !stagedFiles.empty() && !synchronousReset(repoDirectory, stagedFiles, errorMessage)) return RevertFailed; + QStringList filesToRevert = unstagedFiles; + if (revertStaging) + filesToRevert += stagedFiles; // Finally revert! - if (!synchronousCheckoutFiles(repoDirectory, stagedFiles + unstagedFiles, QString(), errorMessage)) + if (!synchronousCheckoutFiles(repoDirectory, filesToRevert, QString(), errorMessage, revertStaging)) return RevertFailed; return RevertOk; } -void GitClient::revert(const QStringList &files) +void GitClient::revert(const QStringList &files, bool revertStaging) { bool isDirectory; QString errorMessage; - switch (revertI(files, &isDirectory, &errorMessage)) { + switch (revertI(files, &isDirectory, &errorMessage, revertStaging)) { case RevertOk: m_plugin->gitVersionControl()->emitFilesChanged(files); break; diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 3d65928b6c8ddc8e499e43dab5dc025160b92b43..8c7670d021400ae386001c8cd355809b8cfc76cc 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -106,7 +106,8 @@ public: bool synchronousInit(const QString &workingDirectory); bool synchronousCheckoutFiles(const QString &workingDirectory, QStringList files = QStringList(), - QString revision = QString(), QString *errorMessage = 0); + QString revision = QString(), QString *errorMessage = 0, + bool revertStaging = true); // Checkout branch bool synchronousCheckoutBranch(const QString &workingDirectory, const QString &branch, QString *errorMessage = 0); @@ -156,7 +157,7 @@ public: void subversionLog(const QString &workingDirectory); void stashPop(const QString &workingDirectory); - void revert(const QStringList &files); + void revert(const QStringList &files, bool revertStaging); void branchList(const QString &workingDirectory); void stashList(const QString &workingDirectory); bool synchronousStashList(const QString &workingDirectory, @@ -241,7 +242,10 @@ private: unsigned synchronousGitVersion(bool silent, QString *errorMessage = 0); enum RevertResult { RevertOk, RevertUnchanged, RevertCanceled, RevertFailed }; - RevertResult revertI(QStringList files, bool *isDirectory, QString *errorMessage); + RevertResult revertI(QStringList files, + bool *isDirectory, + QString *errorMessage, + bool revertStaging); void connectRepositoryChanged(const QString & repository, GitCommand *cmd); void pull(const QString &workingDirectory, bool rebase); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index b54607b447980b8f742bde6c4323d4ee33cbc44d..e5f17b0c5fb81669a201696dcf0b87122c6d1cf1 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -334,9 +334,15 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage) globalcontext, true, SLOT(blameFile())); parameterActionCommand.second->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+B"))); + parameterActionCommand + = createFileAction(actionManager, gitContainer, + tr("Undo Unstaged Changes"), tr("Undo Unstaged Changes for \"%1\""), + QLatin1String("Git.UndoUnstaged"), globalcontext, + true, SLOT(undoUnstagedFileChanges())); + parameterActionCommand = createFileAction(actionManager, gitContainer, - tr("Undo Changes"), tr("Undo Changes for \"%1\""), + tr("Undo Uncommitted Changes"), tr("Undo Uncommitted Changes for \"%1\""), QLatin1String("Git.Undo"), globalcontext, true, SLOT(undoFileChanges())); parameterActionCommand.second->setDefaultKeySequence(QKeySequence(tr("Alt+G,Alt+U"))); @@ -560,12 +566,17 @@ void GitPlugin::logProject() m_gitClient->log(state.currentProjectTopLevel(), state.relativeCurrentProject()); } -void GitPlugin::undoFileChanges() +void GitPlugin::undoFileChanges(bool revertStaging) { const VCSBase::VCSBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return) Core::FileChangeBlocker fcb(state.currentFile()); - m_gitClient->revert(QStringList(state.currentFile())); + m_gitClient->revert(QStringList(state.currentFile()), revertStaging); +} + +void GitPlugin::undoUnstagedFileChanges() +{ + undoFileChanges(false); } void GitPlugin::undoRepositoryChanges() diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 676362cc6902c36fe7094363d4c4f3f86ee81ba3..16852d9cd9bc86d91fd7c92e2bdb204cc971f093 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -108,7 +108,8 @@ private slots: void logFile(); void blameFile(); void logProject(); - void undoFileChanges(); + void undoFileChanges(bool revertStaging = true); + void undoUnstagedFileChanges(); void undoRepositoryChanges(); void stageFile(); void unstageFile();