diff options
author | Artur Shepilko <artur.shepilko@nomadbyte.com> | 2018-07-16 12:25:41 -0500 |
---|---|---|
committer | Artur Shepilko <artur.shepilko@nomadbyte.com> | 2018-08-08 17:15:00 +0000 |
commit | 88e11284ea0db367ce763388efcc9b566684f65c (patch) | |
tree | ffadb096e45a6b871df12ea50a31f1ffc1dc51f0 | |
parent | b1e1cdef867f73b1a999e583c09de61506509911 (diff) |
Add support for annotation of any given revision4.7
- Parent commits are also accessible from Annotate context menu
- The client functionality was added in `fossil v2.4`
Change-Id: Ia6096432cb1151388b5aebca30a6d25c1c6079f4
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
-rw-r--r-- | plugins/fossil/fossilclient.cpp | 62 | ||||
-rw-r--r-- | plugins/fossil/fossilclient.h | 6 | ||||
-rw-r--r-- | plugins/fossil/fossileditor.cpp | 42 | ||||
-rw-r--r-- | plugins/fossil/fossileditor.h | 5 | ||||
-rw-r--r-- | plugins/fossil/fossilplugin.cpp | 5 | ||||
-rw-r--r-- | plugins/fossil/revisioninfo.cpp | 9 | ||||
-rw-r--r-- | plugins/fossil/revisioninfo.h | 7 |
7 files changed, 111 insertions, 25 deletions
diff --git a/plugins/fossil/fossilclient.cpp b/plugins/fossil/fossilclient.cpp index 6d688a7..8dbc225 100644 --- a/plugins/fossil/fossilclient.cpp +++ b/plugins/fossil/fossilclient.cpp @@ -99,7 +99,7 @@ public: // This way the annotated line number would not get offset by the version list. settings.setValue(FossilSettings::annotateListVersionsKey, false); - mapSetting(addToggleButton(QLatin1String("--log"), tr("List Versions")), + mapSetting(addToggleButton("--log", tr("List Versions")), settings.boolPointer(FossilSettings::annotateListVersionsKey)); } }; @@ -342,7 +342,23 @@ QList<BranchInfo> FossilClient::synchronousBranchQuery(const QString &workingDir return branches; } -RevisionInfo FossilClient::synchronousRevisionQuery(const QString &workingDirectory, const QString &id) +QStringList FossilClient::parseRevisionCommentLine(const QString &commentLine) +{ + // "comment: This is a (test) commit message (user: the.name)" + + const QRegularExpression commentRx("^comment:\\s+(.*)\\s\\(user:\\s(.*)\\)$", + QRegularExpression::CaseInsensitiveOption); + QTC_ASSERT(commentRx.isValid(), return QStringList()); + + const QRegularExpressionMatch match = commentRx.match(commentLine); + if (!match.hasMatch()) + return QStringList(); + + return QStringList({match.captured(1), match.captured(2)}); +} + +RevisionInfo FossilClient::synchronousRevisionQuery(const QString &workingDirectory, const QString &id, + bool getCommentMsg) const { // Query details of the given revision/check-out id, // if none specified, provide information about current revision @@ -361,6 +377,9 @@ RevisionInfo FossilClient::synchronousRevisionQuery(const QString &workingDirect QString revisionId; QString parentId; + QStringList mergeParentIds; + QString commentMsg; + QString committer; const QRegularExpression idRx("([0-9a-f]{5,40})"); QTC_ASSERT(idRx.isValid(), return RevisionInfo()); @@ -376,6 +395,15 @@ RevisionInfo FossilClient::synchronousRevisionQuery(const QString &workingDirect const QRegularExpressionMatch idMatch = idRx.match(l); if (idMatch.hasMatch()) parentId = idMatch.captured(1); + } else if (l.startsWith("merged-from: ", Qt::CaseInsensitive)) { + const QRegularExpressionMatch idMatch = idRx.match(l); + if (idMatch.hasMatch()) + mergeParentIds.append(idMatch.captured(1)); + } else if (getCommentMsg + && l.startsWith("comment: ", Qt::CaseInsensitive)) { + const QStringList commentLineParts = parseRevisionCommentLine(l); + commentMsg = commentLineParts.value(0); + committer = commentLineParts.value(1); } } @@ -385,7 +413,7 @@ RevisionInfo FossilClient::synchronousRevisionQuery(const QString &workingDirect if (parentId.isEmpty()) parentId = revisionId; // root - return RevisionInfo(revisionId, parentId); + return RevisionInfo(revisionId, parentId, mergeParentIds, commentMsg, committer); } QStringList FossilClient::synchronousTagQuery(const QString &workingDirectory, const QString &id) @@ -452,8 +480,7 @@ RepositorySettings FossilClient::synchronousSettingsQuery(const QString &working || lcValue == "2") repoSettings.autosync = RepositorySettings::AutosyncPullOnly; } - - if (property == "ssl-identity") { + else if (property == "ssl-identity") { repoSettings.sslIdentityFile = value; } } @@ -582,6 +609,7 @@ QString FossilClient::synchronousTopic(const QString &workingDirectory) return QString(); // return current branch name + const BranchInfo branchInfo = synchronousCurrentBranch(workingDirectory); if (branchInfo.name().isEmpty()) return QString(); @@ -726,7 +754,7 @@ VcsBase::VcsBaseEditorWidget *FossilClient::annotate( QString vcsCmdString = vcsCommandString(AnnotateCommand); const Core::Id kind = vcsEditorKind(AnnotateCommand); - const QString id = VcsBase::VcsBaseEditor::getSource(workingDir, QStringList(file)); + const QString id = VcsBase::VcsBaseEditor::getTitleId(workingDir, QStringList(file), revision); const QString title = vcsEditorTitle(vcsCmdString, id); const QString source = VcsBase::VcsBaseEditor::getSource(workingDir, file); @@ -734,13 +762,6 @@ VcsBase::VcsBaseEditorWidget *FossilClient::annotate( VcsBase::VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); - // We need to be able to re-query the configuration widget for the arguments - // each time the Annotate is requested from the main menu. This allows processing of - // the effective args controlled via configuration widget. - // However VcsBaseEditorWidget no longer stores the configuration widget and thus - // does not support configurationWidget() query. - // So we re-implement the configurationWidget() in FossilEditorWidget sub-class. - auto *fossilEditor = qobject_cast<FossilEditorWidget *>(editor); QTC_ASSERT(fossilEditor, return editor); @@ -769,7 +790,11 @@ VcsBase::VcsBaseEditorWidget *FossilClient::annotate( effectiveArgs.removeAt(pos); } QStringList args(vcsCmdString); - args << revisionSpec(revision) << effectiveArgs << file; + if (!revision.isEmpty() + && supportedFeatures().testFlag(AnnotateRevisionFeature)) + args << "-r" << revision; + + args << effectiveArgs << file; // When version list requested, ignore the source line. if (args.contains("--log")) @@ -805,7 +830,7 @@ bool FossilClient::managesFile(const QString &workingDirectory, const QString &f if (response.result != Utils::SynchronousProcessResponse::Finished) return false; QString output = sanitizeFossilOutput(response.stdOut()); - return !output.startsWith("no history for file"); + return !output.startsWith("no history for file", Qt::CaseInsensitive); } unsigned int FossilClient::binaryVersion() const @@ -851,8 +876,10 @@ FossilClient::SupportedFeatures FossilClient::supportedFeatures() const const unsigned int version = binaryVersion(); - if (version < 0x13000) { - features &= ~TimelinePathFeature; + if (version < 0x20400) { + features &= ~AnnotateRevisionFeature; + if (version < 0x13000) + features &= ~TimelinePathFeature; if (version < 0x12900) features &= ~DiffIgnoreWhiteSpaceFeature; if (version < 0x12800) { @@ -860,6 +887,7 @@ FossilClient::SupportedFeatures FossilClient::supportedFeatures() const features &= ~TimelineWidthFeature; } } + return features; } diff --git a/plugins/fossil/fossilclient.h b/plugins/fossil/fossilclient.h index e759314..3b0a414 100644 --- a/plugins/fossil/fossilclient.h +++ b/plugins/fossil/fossilclient.h @@ -48,11 +48,13 @@ public: TimelineWidthFeature = 0x4, DiffIgnoreWhiteSpaceFeature = 0x8, TimelinePathFeature = 0x10, + AnnotateRevisionFeature = 0x20, AllSupportedFeatures = // | all defined features AnnotateBlameFeature | TimelineWidthFeature | DiffIgnoreWhiteSpaceFeature | TimelinePathFeature + | AnnotateRevisionFeature }; Q_DECLARE_FLAGS(SupportedFeatures, SupportedFeature) @@ -64,7 +66,8 @@ public: unsigned int synchronousBinaryVersion() const; BranchInfo synchronousCurrentBranch(const QString &workingDirectory); QList<BranchInfo> synchronousBranchQuery(const QString &workingDirectory); - RevisionInfo synchronousRevisionQuery(const QString &workingDirectory, const QString &id = QString()); + RevisionInfo synchronousRevisionQuery(const QString &workingDirectory, const QString &id = QString(), + bool getCommentMsg = false) const; QStringList synchronousTagQuery(const QString &workingDirectory, const QString &id = QString()); RepositorySettings synchronousSettingsQuery(const QString &workingDirectory); bool synchronousSetSetting(const QString &workingDirectory, const QString &property, @@ -113,6 +116,7 @@ public: private: static QList<BranchInfo> branchListFromOutput(const QString &output, const BranchInfo::BranchFlags defaultFlags = 0); + static QStringList parseRevisionCommentLine(const QString &commentLine); QString sanitizeFossilOutput(const QString &output) const; QString vcsCommandString(VcsCommandTag cmd) const final; diff --git a/plugins/fossil/fossileditor.cpp b/plugins/fossil/fossileditor.cpp index 6297f7d..74a7c86 100644 --- a/plugins/fossil/fossileditor.cpp +++ b/plugins/fossil/fossileditor.cpp @@ -124,8 +124,48 @@ QString FossilEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) const return QString(); } +QString FossilEditorWidget::decorateVersion(const QString &revision) const +{ + static const int shortChangesetIdSize(10); + static const int maxTextSize(120); + + const QFileInfo fi(source()); + const QString workingDirectory = fi.absolutePath(); + FossilClient *client = FossilPlugin::instance()->client(); + RevisionInfo revisionInfo = + client->synchronousRevisionQuery(workingDirectory, revision, true); + + // format: 'revision (committer "comment...")' + QString output = revision.left(shortChangesetIdSize) + + " (" + revisionInfo.committer + + " \"" + revisionInfo.commentMsg.left(maxTextSize); + + if (output.size() > maxTextSize) { + output.truncate(maxTextSize - 3); + output.append("..."); + } + output.append("\")"); + return output; +} + +QStringList FossilEditorWidget::annotationPreviousVersions(const QString &revision) const +{ + QStringList revisions; + const QFileInfo fi(source()); + const QString workingDirectory = fi.absolutePath(); + FossilClient *client = FossilPlugin::instance()->client(); + RevisionInfo revisionInfo = + client->synchronousRevisionQuery(workingDirectory, revision); + if (revisionInfo.parentId.isEmpty()) + return QStringList(); + + revisions.append(revisionInfo.parentId); + revisions.append(revisionInfo.mergeParentIds); + return revisions; +} -VcsBase::BaseAnnotationHighlighter *FossilEditorWidget::createAnnotationHighlighter(const QSet<QString> &changes) const +VcsBase::BaseAnnotationHighlighter *FossilEditorWidget::createAnnotationHighlighter( + const QSet<QString> &changes) const { return new FossilAnnotationHighlighter(changes); } diff --git a/plugins/fossil/fossileditor.h b/plugins/fossil/fossileditor.h index ee9b6b4..db43d41 100644 --- a/plugins/fossil/fossileditor.h +++ b/plugins/fossil/fossileditor.h @@ -43,7 +43,10 @@ public: private: QSet<QString> annotationChanges() const final; QString changeUnderCursor(const QTextCursor &cursor) const final; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes) const final; + QString decorateVersion(const QString &revision) const final; + QStringList annotationPreviousVersions(const QString &revision) const final; + VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( + const QSet<QString> &changes) const final; FossilEditorWidgetPrivate *d; }; diff --git a/plugins/fossil/fossilplugin.cpp b/plugins/fossil/fossilplugin.cpp index 2d48bcc..206e5bc 100644 --- a/plugins/fossil/fossilplugin.cpp +++ b/plugins/fossil/fossilplugin.cpp @@ -285,8 +285,9 @@ void FossilPlugin::logCurrentFile() if (features.testFlag(FossilClient::TimelineWidthFeature)) extraOptions << "-W" << QString::number(m_client->settings().intValue(FossilSettings::timelineWidthKey)); - // annotate only supported for current revision, so disable context menu - bool enableAnnotationContextMenu = false; + // disable annotate context menu for older client versions, used to be supported for current revision only + bool enableAnnotationContextMenu = features.testFlag(FossilClient::AnnotateRevisionFeature); + m_client->logCurrentFile(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()), extraOptions, enableAnnotationContextMenu); } diff --git a/plugins/fossil/revisioninfo.cpp b/plugins/fossil/revisioninfo.cpp index a239226..aeacfdc 100644 --- a/plugins/fossil/revisioninfo.cpp +++ b/plugins/fossil/revisioninfo.cpp @@ -28,9 +28,14 @@ namespace Fossil { namespace Internal { -RevisionInfo::RevisionInfo(const QString &revisionId, const QString &parent) : +RevisionInfo::RevisionInfo(const QString &revisionId, const QString &parent, + const QStringList &mergeParents, const QString &comment, + const QString &user) : id(revisionId), - parentId(parent) + parentId(parent), + mergeParentIds(mergeParents), + commentMsg(comment), + committer(user) { } } // namespace Internal diff --git a/plugins/fossil/revisioninfo.h b/plugins/fossil/revisioninfo.h index 247b450..11cd4a7 100644 --- a/plugins/fossil/revisioninfo.h +++ b/plugins/fossil/revisioninfo.h @@ -36,10 +36,15 @@ namespace Internal { class RevisionInfo { public: - explicit RevisionInfo(const QString &revisionId = QString(), const QString &parent = QString()); + explicit RevisionInfo(const QString &revisionId = QString(), const QString &parent = QString(), + const QStringList &mergeParents = QStringList(), + const QString &comment = QString(), const QString &user = QString()); const QString id; const QString parentId; + const QStringList mergeParentIds; + const QString commentMsg; + const QString committer; }; |