DiffEditor: Save description along with diff.

Save complete, git-applicable patch when saving the result of
for example 'git show'. Strips some Creator-specific tags
off the description and reformats the description such
that it is accepted by git.

Change-Id: I739d85a7263f97e2149a2794974ba026f2eca067
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Friedemann Kleint
2014-11-11 16:27:23 +01:00
parent e123f5a4d9
commit 9605244f6d
5 changed files with 68 additions and 21 deletions

View File

@@ -102,6 +102,44 @@ bool DiffEditorController::isIgnoreWhitespace() const
return m_ignoreWhitespace; return m_ignoreWhitespace;
} }
// ### fixme: git-specific handling should be done in the git plugin:
// Remove unexpanded branches and follows-tag, clear indentation
// and create E-mail
static void formatGitDescription(QString *description)
{
QString result;
result.reserve(description->size());
foreach (QString line, description->split(QLatin1Char('\n'))) {
if (line.startsWith(QLatin1String("commit "))
|| line.startsWith(QLatin1String("Branches: <Expand>"))) {
continue;
}
if (line.startsWith(QLatin1String("Author: ")))
line.replace(0, 8, QStringLiteral("From: "));
else if (line.startsWith(QLatin1String(" ")))
line.remove(0, 4);
result.append(line);
result.append(QLatin1Char('\n'));
}
*description = result;
}
QString DiffEditorController::contents() const
{
QString result = m_description;
const int formattingOptions = DiffUtils::GitFormat;
if (formattingOptions & DiffUtils::GitFormat)
formatGitDescription(&result);
const QString diff = DiffUtils::makePatch(diffFiles(), formattingOptions);
if (!diff.isEmpty()) {
if (!result.isEmpty())
result += QLatin1Char('\n');
result += diff;
}
return result;
}
QString DiffEditorController::makePatch(bool revert, bool addPrefix) const QString DiffEditorController::makePatch(bool revert, bool addPrefix) const
{ {
if (m_diffFileIndex < 0 || m_chunkIndex < 0) if (m_diffFileIndex < 0 || m_chunkIndex < 0)

View File

@@ -57,6 +57,7 @@ public:
bool isIgnoreWhitespace() const; bool isIgnoreWhitespace() const;
QString makePatch(bool revert, bool addPrefix = false) const; QString makePatch(bool revert, bool addPrefix = false) const;
QString contents() const;
DiffEditorReloader *reloader() const; DiffEditorReloader *reloader() const;
void setReloader(DiffEditorReloader *reloader); void setReloader(DiffEditorReloader *reloader);

View File

@@ -78,9 +78,7 @@ bool DiffEditorDocument::save(QString *errorString, const QString &fileName, boo
Q_UNUSED(errorString) Q_UNUSED(errorString)
Q_UNUSED(autoSave) Q_UNUSED(autoSave)
const QString contents = DiffUtils::makePatch(m_controller->diffFiles()); const bool ok = write(fileName, format(), m_controller->contents(), errorString);
const bool ok = write(fileName, format(), contents, errorString);
if (!ok) if (!ok)
return false; return false;

View File

@@ -31,6 +31,7 @@
#include "diffutils.h" #include "diffutils.h"
#include "differ.h" #include "differ.h"
#include <QStringList> #include <QStringList>
#include <QTextStream>
#include "texteditor/fontsettings.h" #include "texteditor/fontsettings.h"
namespace DiffEditor { namespace DiffEditor {
@@ -483,31 +484,35 @@ QString DiffUtils::makePatch(const ChunkData &chunkData,
return diffText; return diffText;
} }
QString DiffUtils::makePatch(const QList<FileData> &fileDataList) QString DiffUtils::makePatch(const QList<FileData> &fileDataList, unsigned formatFlags)
{ {
QString diffText; QString diffText;
QTextStream str(&diffText);
for (int i = 0; i < fileDataList.count(); i++) { for (int i = 0; i < fileDataList.count(); i++) {
const FileData &fileData = fileDataList.at(i); const FileData &fileData = fileDataList.at(i);
if (formatFlags & GitFormat) {
str << "diff --git a/" << fileData.leftFileInfo.fileName
<< " b/" << fileData.rightFileInfo.fileName << '\n';
}
if (fileData.binaryFiles) { if (fileData.binaryFiles) {
const QString binaryLine = QLatin1String("Binary files ") str << "Binary files ";
+ fileData.leftFileInfo.fileName if (formatFlags & AddLevel)
+ QLatin1String(" and ") str << "a/";
+ fileData.rightFileInfo.fileName str << fileData.leftFileInfo.fileName << " and ";
+ QLatin1String(" differ\n"); if (formatFlags & AddLevel)
diffText += binaryLine; str << "b/";
str << fileData.rightFileInfo.fileName << " differ\n";
} else { } else {
const QString leftFileInfo = QLatin1String("--- ") str << "--- ";
+ fileData.leftFileInfo.fileName + QLatin1Char('\n'); if (formatFlags & AddLevel)
const QString rightFileInfo = QLatin1String("+++ ") str << "a/";
+ fileData.rightFileInfo.fileName + QLatin1Char('\n'); str << fileData.leftFileInfo.fileName << "\n+++ ";
if (formatFlags & AddLevel)
diffText += leftFileInfo; str << "b/";
diffText += rightFileInfo; str << fileData.rightFileInfo.fileName << '\n';
for (int j = 0; j < fileData.chunks.count(); j++) { for (int j = 0; j < fileData.chunks.count(); j++) {
diffText += makePatch(fileData.chunks.at(j), str << makePatch(fileData.chunks.at(j),
(j == fileData.chunks.count() - 1) (j == fileData.chunks.count() - 1)
&& fileData.lastChunkAtTheEndOfFile); && fileData.lastChunkAtTheEndOfFile);
} }

View File

@@ -130,6 +130,10 @@ public:
class DIFFEDITOR_EXPORT DiffUtils { class DIFFEDITOR_EXPORT DiffUtils {
public: public:
enum PatchFormattingFlags {
AddLevel = 0x1, // Add 'a/' , '/b' for git am
GitFormat = AddLevel | 0x2, // Add line 'diff ..' as git does
};
static ChunkData calculateOriginalData(const QList<Diff> &leftDiffList, static ChunkData calculateOriginalData(const QList<Diff> &leftDiffList,
const QList<Diff> &rightDiffList); const QList<Diff> &rightDiffList);
@@ -146,7 +150,8 @@ public:
const QString &leftFileName, const QString &leftFileName,
const QString &rightFileName, const QString &rightFileName,
bool lastChunk = false); bool lastChunk = false);
static QString makePatch(const QList<FileData> &fileDataList); static QString makePatch(const QList<FileData> &fileDataList,
unsigned formatFlags = 0);
static QList<FileData> readPatch(const QString &patch, static QList<FileData> readPatch(const QString &patch,
bool *ok = 0); bool *ok = 0);
}; };