forked from qt-creator/qt-creator
Git: Support staging a single chunk.
Add context menu in diff editor to stage/unstage a single chunk from the diff. Task-number: QTCREATORBUG-5875 Change-Id: Ic244a0d84b5ed5f66b90d7fe8784fc1b8041d183 Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
c372f7b601
commit
367cfc8419
@@ -1115,6 +1115,8 @@ void GitClient::diff(const QString &workingDirectory,
|
||||
workingDirectory,
|
||||
argWidget);
|
||||
newEditor = vcsEditor->editor();
|
||||
connect(vcsEditor, SIGNAL(diffChunkApplied(VcsBase::DiffChunk)),
|
||||
argWidget, SLOT(executeCommand()));
|
||||
connect(vcsEditor, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)),
|
||||
argWidget, SLOT(executeCommand()));
|
||||
}
|
||||
@@ -1222,6 +1224,8 @@ void GitClient::diff(const QString &workingDirectory,
|
||||
sourceFile,
|
||||
argWidget);
|
||||
newEditor = vcsEditor->editor();
|
||||
connect(vcsEditor, SIGNAL(diffChunkApplied(VcsBase::DiffChunk)),
|
||||
argWidget, SLOT(executeCommand()));
|
||||
connect(vcsEditor, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)),
|
||||
argWidget, SLOT(executeCommand()));
|
||||
}
|
||||
@@ -2433,10 +2437,11 @@ bool GitClient::synchronousCleanList(const QString &workingDirectory, QStringLis
|
||||
}
|
||||
|
||||
bool GitClient::synchronousApplyPatch(const QString &workingDirectory,
|
||||
const QString &file, QString *errorMessage)
|
||||
const QString &file, QString *errorMessage,
|
||||
const QStringList &arguments)
|
||||
{
|
||||
QStringList args;
|
||||
args << QLatin1String("apply") << QLatin1String("--whitespace=fix") << file;
|
||||
args << QLatin1String("apply") << QLatin1String("--whitespace=fix") << arguments << file;
|
||||
QByteArray outputText;
|
||||
QByteArray errorText;
|
||||
const bool rc = fullySynchronousGit(workingDirectory, args, &outputText, &errorText);
|
||||
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
const QStringList &files = QStringList(),
|
||||
QString *errorMessage = 0);
|
||||
bool synchronousCleanList(const QString &workingDirectory, QStringList *files, QStringList *ignoredFiles, QString *errorMessage);
|
||||
bool synchronousApplyPatch(const QString &workingDirectory, const QString &file, QString *errorMessage);
|
||||
bool synchronousApplyPatch(const QString &workingDirectory, const QString &file, QString *errorMessage, const QStringList &arguments = QStringList());
|
||||
bool synchronousInit(const QString &workingDirectory);
|
||||
bool synchronousCheckoutFiles(const QString &workingDirectory,
|
||||
QStringList files = QStringList(),
|
||||
|
||||
@@ -44,9 +44,12 @@
|
||||
#include <QFileInfo>
|
||||
#include <QRegExp>
|
||||
#include <QSet>
|
||||
#include <QTemporaryFile>
|
||||
#include <QDir>
|
||||
|
||||
#include <QTextCursor>
|
||||
#include <QTextBlock>
|
||||
#include <QMessageBox>
|
||||
|
||||
#define CHANGE_PATTERN "[a-f0-9]{7,40}"
|
||||
|
||||
@@ -223,6 +226,53 @@ void GitEditor::revertChange()
|
||||
GitPlugin::instance()->gitClient()->synchronousRevert(workingDirectory, m_currentChange);
|
||||
}
|
||||
|
||||
void GitEditor::stageDiffChunk()
|
||||
{
|
||||
const QAction *a = qobject_cast<QAction *>(sender());
|
||||
QTC_ASSERT(a, return);
|
||||
const VcsBase::DiffChunk chunk = qvariant_cast<VcsBase::DiffChunk>(a->data());
|
||||
return applyDiffChunk(chunk, false);
|
||||
}
|
||||
|
||||
void GitEditor::unstageDiffChunk()
|
||||
{
|
||||
const QAction *a = qobject_cast<QAction *>(sender());
|
||||
QTC_ASSERT(a, return);
|
||||
const VcsBase::DiffChunk chunk = qvariant_cast<VcsBase::DiffChunk>(a->data());
|
||||
return applyDiffChunk(chunk, true);
|
||||
}
|
||||
|
||||
void GitEditor::applyDiffChunk(const VcsBase::DiffChunk& chunk, bool revert)
|
||||
{
|
||||
VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance();
|
||||
QTemporaryFile patchFile;
|
||||
if (!patchFile.open())
|
||||
return;
|
||||
|
||||
const QString baseDir = diffBaseDirectory();
|
||||
patchFile.write(chunk.header);
|
||||
patchFile.write(chunk.chunk);
|
||||
patchFile.close();
|
||||
|
||||
GitClient *client = GitPlugin::instance()->gitClient();
|
||||
QStringList args = QStringList() << QLatin1String("--cached");
|
||||
if (revert)
|
||||
args << QLatin1String("--reverse");
|
||||
QString errorMessage;
|
||||
if (client->synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) {
|
||||
if (errorMessage.isEmpty())
|
||||
outwin->append(tr("Chunk successfully staged"));
|
||||
else
|
||||
outwin->append(errorMessage);
|
||||
if (revert)
|
||||
emit diffChunkReverted(chunk);
|
||||
else
|
||||
emit diffChunkApplied(chunk);
|
||||
} else {
|
||||
outwin->appendError(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
void GitEditor::init()
|
||||
{
|
||||
VcsBase::VcsBaseEditorWidget::init();
|
||||
@@ -233,6 +283,19 @@ void GitEditor::init()
|
||||
new GitRebaseHighlighter(baseTextDocument().data());
|
||||
}
|
||||
|
||||
void GitEditor::addDiffActions(QMenu *menu, const VcsBase::DiffChunk &chunk)
|
||||
{
|
||||
menu->addSeparator();
|
||||
|
||||
QAction *stageAction = menu->addAction(tr("Stage Chunk..."));
|
||||
stageAction->setData(qVariantFromValue(chunk));
|
||||
connect(stageAction, SIGNAL(triggered()), this, SLOT(stageDiffChunk()));
|
||||
|
||||
QAction *unstageAction = menu->addAction(tr("Unstage Chunk..."));
|
||||
unstageAction->setData(qVariantFromValue(chunk));
|
||||
connect(unstageAction, SIGNAL(triggered()), this, SLOT(unstageDiffChunk()));
|
||||
}
|
||||
|
||||
bool GitEditor::open(QString *errorString, const QString &fileName, const QString &realFileName)
|
||||
{
|
||||
bool res = VcsBaseEditorWidget::open(errorString, fileName, realFileName);
|
||||
|
||||
@@ -57,9 +57,13 @@ public slots:
|
||||
private slots:
|
||||
void cherryPickChange();
|
||||
void revertChange();
|
||||
void stageDiffChunk();
|
||||
void unstageDiffChunk();
|
||||
void applyDiffChunk(const VcsBase::DiffChunk& chunk, bool revert);
|
||||
|
||||
private:
|
||||
void init();
|
||||
void addDiffActions(QMenu *menu, const VcsBase::DiffChunk &chunk);
|
||||
bool open(QString *errorString, const QString &fileName, const QString &realFileName);
|
||||
QSet<QString> annotationChanges() const;
|
||||
QString changeUnderCursor(const QTextCursor &) const;
|
||||
|
||||
Reference in New Issue
Block a user