forked from qt-creator/qt-creator
Git: Implement "Fixup previous commit"
Change-Id: Ia2584ff975ed0db614dc878a70ce4adbd5c3ba67 Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
5d325f6b1a
commit
8695fe6d7c
@@ -437,7 +437,8 @@ GitClient::GitClient(GitSettings *settings) :
|
||||
m_cachedGitVersion(0),
|
||||
m_msgWait(tr("Waiting for data...")),
|
||||
m_repositoryChangedSignalMapper(0),
|
||||
m_settings(settings)
|
||||
m_settings(settings),
|
||||
m_disableEditor(false)
|
||||
{
|
||||
QTC_CHECK(settings);
|
||||
connect(Core::ICore::instance(), SIGNAL(saveSettingsRequested()), this, SLOT(saveSettings()));
|
||||
@@ -1701,7 +1702,7 @@ QProcessEnvironment GitClient::processEnvironment() const
|
||||
&& settings()->boolValue(GitSettings::winSetHomeEnvironmentKey)) {
|
||||
environment.insert(QLatin1String("HOME"), QDir::toNativeSeparators(QDir::homePath()));
|
||||
}
|
||||
environment.insert(QLatin1String("GIT_EDITOR"), m_gitQtcEditor);
|
||||
environment.insert(QLatin1String("GIT_EDITOR"), m_disableEditor ? QLatin1String("true") : m_gitQtcEditor);
|
||||
// Set up SSH and C locale (required by git using perl).
|
||||
VcsBase::VcsBasePlugin::setProcessEnvironment(&environment, false);
|
||||
return environment;
|
||||
@@ -2139,6 +2140,8 @@ bool GitClient::getCommitData(const QString &workingDirectory,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FixupCommit:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2155,12 +2158,12 @@ static inline QString msgCommitted(const QString &amendSHA1, int fileCount)
|
||||
|
||||
bool GitClient::addAndCommit(const QString &repositoryDirectory,
|
||||
const GitSubmitEditorPanelData &data,
|
||||
CommitType commitType,
|
||||
const QString &amendSHA1,
|
||||
const QString &messageFile,
|
||||
VcsBase::SubmitFileModel *model)
|
||||
{
|
||||
const QString renameSeparator = QLatin1String(" -> ");
|
||||
const bool amend = !amendSHA1.isEmpty();
|
||||
|
||||
QStringList filesToAdd;
|
||||
QStringList filesToRemove;
|
||||
@@ -2218,15 +2221,19 @@ bool GitClient::addAndCommit(const QString &repositoryDirectory,
|
||||
|
||||
// Do the final commit
|
||||
QStringList args;
|
||||
args << QLatin1String("commit")
|
||||
<< QLatin1String("-F") << QDir::toNativeSeparators(messageFile);
|
||||
if (amend)
|
||||
args << QLatin1String("--amend");
|
||||
const QString &authorString = data.authorString();
|
||||
if (!authorString.isEmpty())
|
||||
args << QLatin1String("--author") << authorString;
|
||||
if (data.bypassHooks)
|
||||
args << QLatin1String("--no-verify");
|
||||
args << QLatin1String("commit");
|
||||
if (commitType == FixupCommit) {
|
||||
args << QLatin1String("--fixup") << amendSHA1;
|
||||
} else {
|
||||
args << QLatin1String("-F") << QDir::toNativeSeparators(messageFile);
|
||||
if (commitType == AmendCommit)
|
||||
args << QLatin1String("--amend");
|
||||
const QString &authorString = data.authorString();
|
||||
if (!authorString.isEmpty())
|
||||
args << QLatin1String("--author") << authorString;
|
||||
if (data.bypassHooks)
|
||||
args << QLatin1String("--no-verify");
|
||||
}
|
||||
|
||||
QByteArray outputText;
|
||||
QByteArray errorText;
|
||||
@@ -2544,11 +2551,16 @@ bool GitClient::synchronousCherryPick(const QString &workingDirectory, const QSt
|
||||
}
|
||||
|
||||
void GitClient::interactiveRebase(const QString &workingDirectory, const QString &commit,
|
||||
StashGuard &stashGuard)
|
||||
StashGuard &stashGuard, bool fixup)
|
||||
{
|
||||
QStringList arguments;
|
||||
arguments << QLatin1String("rebase") << QLatin1String("-i") << commit + QLatin1Char('^');
|
||||
arguments << QLatin1String("rebase") << QLatin1String("-i");
|
||||
if (fixup)
|
||||
arguments << QLatin1String("--autosquash");
|
||||
arguments << commit + QLatin1Char('^');
|
||||
outputWindow()->appendCommand(workingDirectory, settings()->stringValue(GitSettings::binaryPathKey), arguments);
|
||||
if (fixup)
|
||||
m_disableEditor = true;
|
||||
VcsBase::Command *command = createCommand(workingDirectory, 0, true);
|
||||
command->addJob(arguments, -1);
|
||||
command->execute();
|
||||
@@ -2557,6 +2569,8 @@ void GitClient::interactiveRebase(const QString &workingDirectory, const QString
|
||||
connect(command, SIGNAL(errorText(QString)), rebaseManager, SLOT(readStdErr(QString)));
|
||||
connect(command, SIGNAL(finished(bool,int,QVariant)),
|
||||
rebaseManager, SLOT(finished(bool,int,QVariant)));
|
||||
if (fixup)
|
||||
m_disableEditor = false;
|
||||
}
|
||||
|
||||
QString GitClient::msgNoChangedFiles()
|
||||
|
||||
@@ -238,7 +238,7 @@ public:
|
||||
bool synchronousRevert(const QString &workingDirectory, const QString &commit);
|
||||
bool synchronousCherryPick(const QString &workingDirectory, const QString &commit);
|
||||
void interactiveRebase(const QString &workingDirectory, const QString &commit,
|
||||
StashGuard &stashGuard);
|
||||
StashGuard &stashGuard, bool fixup);
|
||||
void synchronousAbortCommand(const QString &workingDir, const QString &abortCommand);
|
||||
|
||||
// git svn support (asynchronous).
|
||||
@@ -267,6 +267,7 @@ public:
|
||||
|
||||
bool addAndCommit(const QString &workingDirectory,
|
||||
const GitSubmitEditorPanelData &data,
|
||||
CommitType commitType,
|
||||
const QString &amendSHA1,
|
||||
const QString &messageFile,
|
||||
VcsBase::SubmitFileModel *model);
|
||||
@@ -376,6 +377,7 @@ private:
|
||||
QSignalMapper *m_repositoryChangedSignalMapper;
|
||||
GitSettings *m_settings;
|
||||
QString m_gitQtcEditor;
|
||||
bool m_disableEditor;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -424,6 +424,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
createRepositoryAction(localRepositoryMenu,
|
||||
tr("Amend Last Commit..."), Core::Id("Git.AmendCommit"),
|
||||
globalcontext, true, SLOT(startAmendCommit()));
|
||||
|
||||
createRepositoryAction(localRepositoryMenu,
|
||||
tr("Fixup Previous Commit..."), Core::Id("Git.FixupCommit"),
|
||||
globalcontext, true, SLOT(startFixupCommit()));
|
||||
// --------------
|
||||
localRepositoryMenu->addSeparator(globalcontext);
|
||||
|
||||
@@ -769,7 +773,7 @@ void GitPlugin::startRebase()
|
||||
return;
|
||||
const QString change = dialog.commit();
|
||||
if (!change.isEmpty())
|
||||
m_gitClient->interactiveRebase(workingDirectory, change, *stashGuard.take());
|
||||
m_gitClient->interactiveRebase(workingDirectory, change, *stashGuard.take(), false);
|
||||
}
|
||||
|
||||
void GitPlugin::startChangeRelatedAction()
|
||||
@@ -879,6 +883,11 @@ void GitPlugin::startAmendCommit()
|
||||
startCommit(AmendCommit);
|
||||
}
|
||||
|
||||
void GitPlugin::startFixupCommit()
|
||||
{
|
||||
startCommit(FixupCommit);
|
||||
}
|
||||
|
||||
void GitPlugin::startCommit()
|
||||
{
|
||||
startCommit(SimpleCommit);
|
||||
@@ -906,7 +915,6 @@ void GitPlugin::startCommit(CommitType commitType)
|
||||
// Store repository for diff and the original list of
|
||||
// files to be able to unstage files the user unchecks
|
||||
m_submitRepository = data.panelInfo.repository;
|
||||
m_commitAmendSHA1 = data.amendSHA1;
|
||||
|
||||
// Start new temp file with message template
|
||||
Utils::TempFileSaver saver;
|
||||
@@ -1009,17 +1017,29 @@ bool GitPlugin::submitEditorAboutToClose()
|
||||
// Go ahead!
|
||||
VcsBase::SubmitFileModel *model = qobject_cast<VcsBase::SubmitFileModel *>(editor->fileModel());
|
||||
bool closeEditor = true;
|
||||
if (model->hasCheckedFiles() || !m_commitAmendSHA1.isEmpty()) {
|
||||
CommitType commitType = editor->commitType();
|
||||
QString amendSHA1 = editor->amendSHA1();
|
||||
if (model->hasCheckedFiles() || !amendSHA1.isEmpty()) {
|
||||
// get message & commit
|
||||
if (!Core::DocumentManager::saveDocument(editorDocument))
|
||||
return false;
|
||||
|
||||
closeEditor = m_gitClient->addAndCommit(m_submitRepository, editor->panelData(),
|
||||
m_commitAmendSHA1, m_commitMessageFileName, model);
|
||||
commitType, amendSHA1,
|
||||
m_commitMessageFileName, model);
|
||||
}
|
||||
if (closeEditor) {
|
||||
cleanCommitMessageFile();
|
||||
m_gitClient->continueCommandIfNeeded(m_submitRepository);
|
||||
if (commitType == FixupCommit) {
|
||||
QScopedPointer<GitClient::StashGuard> stashGuard(
|
||||
new GitClient::StashGuard(m_submitRepository, QLatin1String("Rebase-fixup"),
|
||||
NoPrompt));
|
||||
if (stashGuard->stashingFailed())
|
||||
return false;
|
||||
m_gitClient->interactiveRebase(m_submitRepository, amendSHA1, *stashGuard.take(), true);
|
||||
} else {
|
||||
m_gitClient->continueCommandIfNeeded(m_submitRepository);
|
||||
}
|
||||
}
|
||||
return closeEditor;
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ private slots:
|
||||
void gitClientMemberFuncRepositoryAction();
|
||||
|
||||
void startAmendCommit();
|
||||
void startFixupCommit();
|
||||
void stash();
|
||||
void stashSnapshot();
|
||||
void branchList();
|
||||
@@ -231,7 +232,6 @@ private:
|
||||
QPointer<RemoteDialog> m_remoteDialog;
|
||||
QString m_submitRepository;
|
||||
QString m_commitMessageFileName;
|
||||
QString m_commitAmendSHA1;
|
||||
bool m_submitActionTriggered;
|
||||
|
||||
GitSettings m_settings;
|
||||
|
||||
@@ -38,7 +38,8 @@ namespace Internal {
|
||||
enum CommitType
|
||||
{
|
||||
SimpleCommit,
|
||||
AmendCommit
|
||||
AmendCommit,
|
||||
FixupCommit
|
||||
};
|
||||
|
||||
// Todo: Add user name and password?
|
||||
|
||||
@@ -103,14 +103,17 @@ const GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget() const
|
||||
|
||||
void GitSubmitEditor::setCommitData(const CommitData &d)
|
||||
{
|
||||
m_commitEncoding = d.commitEncoding;
|
||||
m_workingDirectory = d.panelInfo.repository;
|
||||
m_commitType = d.commitType;
|
||||
m_amendSHA1 = d.amendSHA1;
|
||||
|
||||
GitSubmitEditorWidget *w = submitEditorWidget();
|
||||
w->initialize(m_commitType, m_workingDirectory);
|
||||
w->setPanelData(d.panelData);
|
||||
w->setPanelInfo(d.panelInfo);
|
||||
w->setHasUnmerged(false);
|
||||
|
||||
m_commitEncoding = d.commitEncoding;
|
||||
m_workingDirectory = d.panelInfo.repository;
|
||||
m_commitType = d.commitType;
|
||||
setEmptyFileListEnabled(m_commitType == AmendCommit); // Allow for just correcting the message
|
||||
|
||||
m_model = new GitSubmitFileModel(this);
|
||||
@@ -178,6 +181,12 @@ GitSubmitEditorPanelData GitSubmitEditor::panelData() const
|
||||
return submitEditorWidget()->panelData();
|
||||
}
|
||||
|
||||
QString GitSubmitEditor::amendSHA1() const
|
||||
{
|
||||
QString commit = submitEditorWidget()->amendSHA1();
|
||||
return commit.isEmpty() ? m_amendSHA1 : commit;
|
||||
}
|
||||
|
||||
QByteArray GitSubmitEditor::fileContents() const
|
||||
{
|
||||
const QString &text = submitEditorWidget()->descriptionText();
|
||||
|
||||
@@ -56,6 +56,8 @@ public:
|
||||
void setCommitData(const CommitData &);
|
||||
GitSubmitEditorPanelData panelData() const;
|
||||
bool forceClose() const { return m_forceClose; }
|
||||
CommitType commitType() const { return m_commitType; }
|
||||
QString amendSHA1() const;
|
||||
|
||||
signals:
|
||||
void diff(const QStringList &unstagedFiles, const QStringList &stagedFiles);
|
||||
@@ -75,6 +77,7 @@ private:
|
||||
VcsBase::SubmitFileModel *m_model;
|
||||
QString m_commitEncoding;
|
||||
CommitType m_commitType;
|
||||
QString m_amendSHA1;
|
||||
bool m_forceClose;
|
||||
QString m_workingDirectory;
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "gitsubmiteditorwidget.h"
|
||||
#include "commitdata.h"
|
||||
#include "logchangedialog.h"
|
||||
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
@@ -40,7 +41,9 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QGroupBox>
|
||||
#include <QRegExp>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
@@ -120,10 +123,11 @@ void GitSubmitHighlighter::highlightBlock(const QString &text)
|
||||
GitSubmitEditorWidget::GitSubmitEditorWidget(QWidget *parent) :
|
||||
VcsBase::SubmitEditorWidget(parent),
|
||||
m_gitSubmitPanel(new QWidget),
|
||||
m_hasUnmerged(false)
|
||||
m_logChangeWidget(0),
|
||||
m_hasUnmerged(false),
|
||||
m_isInitialized(false)
|
||||
{
|
||||
m_gitSubmitPanelUi.setupUi(m_gitSubmitPanel);
|
||||
insertTopWidget(m_gitSubmitPanel);
|
||||
new GitSubmitHighlighter(descriptionEdit());
|
||||
|
||||
m_emailValidator = new QRegExpValidator(QRegExp(QLatin1String("[^@ ]+@[^@ ]+\\.[a-zA-Z]+")), this);
|
||||
@@ -144,11 +148,35 @@ void GitSubmitEditorWidget::setPanelInfo(const GitSubmitEditorPanelInfo &info)
|
||||
m_gitSubmitPanelUi.branchLabel->setText(info.branch);
|
||||
}
|
||||
|
||||
QString GitSubmitEditorWidget::amendSHA1() const
|
||||
{
|
||||
return m_logChangeWidget ? m_logChangeWidget->commit() : QString();
|
||||
}
|
||||
|
||||
void GitSubmitEditorWidget::setHasUnmerged(bool e)
|
||||
{
|
||||
m_hasUnmerged = e;
|
||||
}
|
||||
|
||||
void GitSubmitEditorWidget::initialize(CommitType commitType, const QString &repository)
|
||||
{
|
||||
if (m_isInitialized)
|
||||
return;
|
||||
m_isInitialized = true;
|
||||
if (commitType == FixupCommit) {
|
||||
QGroupBox *logChangeGroupBox = new QGroupBox(tr("Select Change"));
|
||||
QVBoxLayout *logChangeLayout = new QVBoxLayout;
|
||||
logChangeGroupBox->setLayout(logChangeLayout);
|
||||
m_logChangeWidget = new LogChangeWidget;
|
||||
m_logChangeWidget->init(repository);
|
||||
logChangeLayout->addWidget(m_logChangeWidget);
|
||||
insertTopWidget(logChangeGroupBox);
|
||||
m_gitSubmitPanelUi.editGroup->hide();
|
||||
hideDescription();
|
||||
}
|
||||
insertTopWidget(m_gitSubmitPanel);
|
||||
}
|
||||
|
||||
GitSubmitEditorPanelData GitSubmitEditorWidget::panelData() const
|
||||
{
|
||||
GitSubmitEditorPanelData rc;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define GITSUBMITEDITORWIDGET_H
|
||||
|
||||
#include "ui_gitsubmitpanel.h"
|
||||
#include "gitsettings.h"
|
||||
|
||||
#include <vcsbase/submiteditorwidget.h>
|
||||
|
||||
@@ -43,6 +44,7 @@ namespace Internal {
|
||||
|
||||
struct GitSubmitEditorPanelInfo;
|
||||
struct GitSubmitEditorPanelData;
|
||||
class LogChangeWidget;
|
||||
|
||||
/* Submit editor widget with 2 additional panes:
|
||||
* 1) Info with branch, description, etc
|
||||
@@ -62,7 +64,9 @@ public:
|
||||
GitSubmitEditorPanelData panelData() const;
|
||||
void setPanelData(const GitSubmitEditorPanelData &data);
|
||||
void setPanelInfo(const GitSubmitEditorPanelInfo &info);
|
||||
QString amendSHA1() const;
|
||||
void setHasUnmerged(bool e);
|
||||
void initialize(CommitType commitType, const QString &repository);
|
||||
|
||||
protected:
|
||||
bool canSubmit() const;
|
||||
@@ -75,9 +79,11 @@ private:
|
||||
bool emailIsValid() const;
|
||||
|
||||
QWidget *m_gitSubmitPanel;
|
||||
LogChangeWidget *m_logChangeWidget;
|
||||
Ui::GitSubmitPanel m_gitSubmitPanelUi;
|
||||
QValidator *m_emailValidator;
|
||||
bool m_hasUnmerged;
|
||||
bool m_isInitialized;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
Reference in New Issue
Block a user