среда, 18 ноября 2009 г.

Mercurial Plugin

Я уже писал про плагин для Perforce. И про то, что из всех систем управления версиями (дальше СУВ), Perforce мне понравился больше всего. Это считая только те, c которыми я работал по крайней мере несколько месяцев. Я их перепробовал несколько, помимо Perforce,- DBPS, Subversion и ClearCase. Все, как видно, централизованные. Самая ужасная- это, наверное, DBPS. Хотя, ClearCase тоже особо не радует. Сейчас всей конторой переходим с ClearCase на SVN. Почему не на Git/Bazaar/Mercurial- не знаю, инженеры решения не принимают и начальство перед ними не отчитывается. :)

От нечего делать, решил таки образоваться в области распределенных СУВ. Нашел очень толковый пост о применимости git, Bazaar и Mercurial, особенно в домашних условиях. Погуглив и почитав обзоры и краткие руководства, быстро понял, что с теорией пора завязывать и надо попробовать что-то ручками. Решил начать с Mercurial (кстати, вот здесь неплохое описание базовых use case'ов), поставил ее пока только под Windows. Заработало все сразу, команды оказались простые- одно удовольствие. Порадовали hg serve и hg merge (с помощью KDiff3). Буду признателен, если кто поделится, каким инструментом для merge пользуется.

Стало интересно, а нельзя ли эту штуку прикрутить к Qt Creator. Он в плане плагинов для распределенных СУВ особо не блещет- "из коробки" поддерживается только Git. Гугление показало, что есть проект плагина для Mercurial за авторством Brian McGillion. Лежит здесь. Последний commit от 21 сентября этого года, так что проект, вроде бы, живой. Ну, плагины- это для меня самое интересное, что в Qt Creator есть, хочется в их устройстве разобраться. И код чужой посмотреть для этого полезно весьма.

Ну, пользуясь проторенной дорожкой, я стал собирать этот самый плагин под Qt Creator 1.2.92. Плагин оказался под 1.2.91, так что без жалоб компилятора не обошлось. Все вылечилось довольно просто, diff в конце этого поста.

Восле сборки и копирования длльки и манифеста в каталог плагинов, можно запускать Qt Creator. Плагин написан изначально под Ubuntu, так что в Options надо поменять команду "hg" на "hg.exe". Есть еще пара вещей, которые можно в коде поправить, а можно и забить. Брайану я написал, посмотрим, что он ответит. UPD: Брайан ответил, что поправит, и что проект был перенесен в основной репозиторий Qt Creator. Я проверил, текущая версия 1.3.80, так что скоро ждем.

Набор команд в плагине- это необходимый минимум: Annotate для текущего файла, Diff, Log, Revert и Status для текущего файла и проекта, Pull, Push, Update, Import, Incoming, Outgoing и, конечно, Commit. Все я пока не пробовал, но на первый взгляд- работает. Из того, чего не хватает- Merge с помощью внешнего инструмента и графа или таблицы коммитов. И еще тагов и веток. Так что есть простор для творчества.

В целом, вещь полезная. Если время будет (ага, разбежался), можно этот плагин превратить в плагин для Bazaar. Или подумать об общих классах для этих двух систем, чтобы не плодить копии.

Обещанный diff:

changeset: 1:b7b7b8d4d0c1
tag: tip
user: Qt Creator Geek
date: Tue Nov 17 23:30:46 2009 -0600
summary: Updated for Qt Creator 1.2.92.

diff --git a/Mercurial.pluginspec b/Mercurial.pluginspec
--- a/Mercurial.pluginspec
+++ b/Mercurial.pluginspec
@@ -1,4 +1,4 @@
-
+
Brian McGillion
(C) 2008-2009 Brian McGillion
@@ -19,9 +19,9 @@
Mercurial integration.
http://www.qtsoftware.com
-
-
-
-
+
+
+
+
diff --git a/mercurialcommitwidget.cpp b/mercurialcommitwidget.cpp
--- a/mercurialcommitwidget.cpp
+++ b/mercurialcommitwidget.cpp
@@ -84,7 +84,7 @@
MercurialCommitWidget::MercurialCommitWidget(QWidget *parent) :
- Core::Utils::SubmitEditorWidget(parent),
+ Utils::SubmitEditorWidget(parent),
mercurialCommitPanel(new QWidget)
{
mercurialCommitPanelUi.setupUi(mercurialCommitPanel);
diff --git a/mercurialcommitwidget.h b/mercurialcommitwidget.h
--- a/mercurialcommitwidget.h
+++ b/mercurialcommitwidget.h
@@ -12,7 +12,7 @@
Some extra fields have been added to the standard SubmitEditorWidget,
to help to conform to the commit style that is used by both git and Mercurial*/
-class MercurialCommitWidget : public Core::Utils::SubmitEditorWidget
+class MercurialCommitWidget : public Utils::SubmitEditorWidget
{
public:
diff --git a/mercurialjobrunner.cpp b/mercurialjobrunner.cpp
--- a/mercurialjobrunner.cpp
+++ b/mercurialjobrunner.cpp
@@ -11,6 +11,8 @@
#include
#include
+#include
+
using namespace Mercurial::Internal;
using namespace Mercurial;
@@ -155,18 +157,18 @@
}
if ((hgProcess.exitStatus() == QProcess::NormalExit) && (hgProcess.exitCode() == 0)) {
- QByteArray stdout = hgProcess.readAllStandardOutput();
+ QByteArray stdOut = hgProcess.readAllStandardOutput();
/*
* sometimes success means output is actually on error channel (stderr)
* e.g. "hg revert" outputs "no changes needed to 'file'" on stderr if file has not changed
* from revision specified
*/
- if (stdout == "")
- stdout = hgProcess.readAllStandardError();
- emit output(stdout);
+ if (stdOut == "")
+ stdOut = hgProcess.readAllStandardError();
+ emit output(stdOut);
} else {
- QByteArray stderr = hgProcess.readAllStandardError();
- emit error(stderr);
+ QByteArray stdErr = hgProcess.readAllStandardError();
+ emit error(stdErr);
}
hgProcess.close();
diff --git a/mercurialplugin.cpp b/mercurialplugin.cpp
--- a/mercurialplugin.cpp
+++ b/mercurialplugin.cpp
@@ -22,6 +22,9 @@
#include
+#include
+#include
+
#include
#include
@@ -216,33 +219,33 @@
{
Core::Command *command;
- annotateFile = new Core::Utils::ParameterAction(tr("Annotate Current File"), tr("Annotate \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ annotateFile = new Utils::ParameterAction(tr("Annotate Current File"), tr("Annotate \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(annotateFile, Constants::ANNOTATE, context);
command->setAttribute(Core::Command::CA_UpdateText);
connect(annotateFile, SIGNAL(triggered()), this, SLOT(annotateCurrentFile()));
mercurialContainer->addAction(command);
- diffFile = new Core::Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ diffFile = new Utils::ParameterAction(tr("Diff Current File"), tr("Diff \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(diffFile, Constants::DIFF, context);
command->setAttribute(Core::Command::CA_UpdateText);
command->setDefaultKeySequence(QKeySequence(tr(Constants::MENUKEY) + tr(Constants::MODIFIER) + "D"));
connect(diffFile, SIGNAL(triggered()), this, SLOT(diffCurrentFile()));
mercurialContainer->addAction(command);
- logFile = new Core::Utils::ParameterAction(tr("Log Current File"), tr("Log \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ logFile = new Utils::ParameterAction(tr("Log Current File"), tr("Log \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(logFile, Constants::LOG, context);
command->setAttribute(Core::Command::CA_UpdateText);
command->setDefaultKeySequence(QKeySequence(tr(Constants::MENUKEY) + tr(Constants::MODIFIER) + "L"));
connect(logFile, SIGNAL(triggered()), this, SLOT(logCurrentFile()));
mercurialContainer->addAction(command);
- revertFile = new Core::Utils::ParameterAction(tr("Revert Current File"), tr("Revert \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ revertFile = new Utils::ParameterAction(tr("Revert Current File"), tr("Revert \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(revertFile, Constants::REVERT, context);
command->setAttribute(Core::Command::CA_UpdateText);
connect(revertFile, SIGNAL(triggered()), this, SLOT(revertCurrentFile()));
mercurialContainer->addAction(command);
- statusFile = new Core::Utils::ParameterAction(tr("Status Current File"), tr("Status \"%1\""), Core::Utils::ParameterAction::AlwaysEnabled, this);
+ statusFile = new Utils::ParameterAction(tr("Status Current File"), tr("Status \"%1\""), Utils::ParameterAction::AlwaysEnabled, this);
command = actionManager->registerAction(statusFile, Constants::STATUS, context);
command->setAttribute(Core::Command::CA_UpdateText);
command->setDefaultKeySequence(QKeySequence(tr(Constants::MENUKEY) + tr(Constants::MODIFIER) + "S"));
diff --git a/mercurialplugin.h b/mercurialplugin.h
--- a/mercurialplugin.h
+++ b/mercurialplugin.h
@@ -20,11 +20,11 @@
class IVersionControl;
class IEditorFactory;
class IEditor;
+} // namespace Core
namespace Utils {
class ParameterAction;
} //namespace Utils
-} // namespace Core
namespace ProjectExplorer {
class ProjectExplorerPlugin;
@@ -137,12 +137,12 @@
QTemporaryFile *changeLog;
//Menu Items (file actions)
- Core::Utils::ParameterAction *annotateFile;
- Core::Utils::ParameterAction *diffFile;
- Core::Utils::ParameterAction *logFile;
- Core::Utils::ParameterAction *renameFile;
- Core::Utils::ParameterAction *revertFile;
- Core::Utils::ParameterAction *statusFile;
+ Utils::ParameterAction *annotateFile;
+ Utils::ParameterAction *diffFile;
+ Utils::ParameterAction *logFile;
+ Utils::ParameterAction *renameFile;
+ Utils::ParameterAction *revertFile;
+ Utils::ParameterAction *statusFile;
//submit editor actions
QAction *editorCommit;
diff --git a/optionspage.cpp b/optionspage.cpp
--- a/optionspage.cpp
+++ b/optionspage.cpp
@@ -12,7 +12,7 @@
QWidget(parent)
{
m_ui.setupUi(this);
- m_ui.commandChooser->setExpectedKind(Core::Utils::PathChooser::Command);
+ m_ui.commandChooser->setExpectedKind(Utils::PathChooser::Command);
m_ui.commandChooser->setPromptDialogTitle(tr("Mercurial Command"));
}
diff --git a/srcdestdialog.cpp b/srcdestdialog.cpp
--- a/srcdestdialog.cpp
+++ b/srcdestdialog.cpp
@@ -9,7 +9,7 @@
m_ui(new Ui::SrcDestDialog)
{
m_ui->setupUi(this);
- m_ui->localPathChooser->setExpectedKind(Core::Utils::PathChooser::Directory);
+ m_ui->localPathChooser->setExpectedKind(Utils::PathChooser::Directory);
}
SrcDestDialog::~SrcDestDialog()
@@ -17,7 +17,7 @@
delete m_ui;
}
-void SrcDestDialog::setPathChooserKind(Core::Utils::PathChooser::Kind kind)
+void SrcDestDialog::setPathChooserKind(Utils::PathChooser::Kind kind)
{
m_ui->localPathChooser->setExpectedKind(kind);
}
diff --git a/srcdestdialog.h b/srcdestdialog.h
--- a/srcdestdialog.h
+++ b/srcdestdialog.h
@@ -18,7 +18,7 @@
SrcDestDialog(QWidget *parent = 0);
~SrcDestDialog();
- void setPathChooserKind(Core::Utils::PathChooser::Kind kind);
+ void setPathChooserKind(Utils::PathChooser::Kind kind);
QString getRepositoryString();
protected:



Комментариев нет:

Отправить комментарий