Вопрос по python – Mercurial Hook - изменить сообщение о коммите pre commit

8

Edit Сделал этот простой хук, чтобы предотвратить ответвление имени & amp; сообщение об ошибке не соответствует идентификатору ошибки.https://gist.github.com/2583189

Таким образом, идея заключается в том, что хук должен добавить & quot; BUGID: хуг & Quot; до конца сообщений коммита, если имя ветви похоже на bug_123 или feature_123. Однако у меня возникают проблемы с нахождением того, как это сделать, поскольку большинство примеров людей, которые ранее не соглашались, не хотят изменять описание набора изменений.

Это то, что я до сих пор. Он обновляет .hg / commit.save с правильным сообщением, но это сообщение никогда не передается в коммит. Однако он отображается в окне сообщений по умолчанию (tortoisehg) следующего коммита. Может быть, pretxncommit - это не правильный крючок?

Могу ли я использовать ловушку предварительной фиксации, прочитать файл commit.save и repo ['amp; tip & apos;]. Branch () и изменить что, если да, то откуда мне взять название ветки?

#
# Fogbugz automaticically add BugID:123 to commit messages based on branch names.
# Your branch name must be in the format feature_123_description or bug_123_description
#

import re
import mercurial, sys, os

_branch_regex = re.compile('(feature|bug|case|bugid|fogbugz)_(\d+)')
_commit_regex = re.compile(r'\b(?P<case>(review|case|bug[zs]?(\s| )*(id)?:?)s?(\s| )*([#:; ]| )+)((([ ,:;#]|and)*)(?P<bugid>\d+))+',re.I)

def pretxncommithook(ui, repo, **kwargs):
    ui.write('hook pretxncommithook running from fogbugz.py\n')
    """
    Checks a single commit message for adherence to commit message rules.

    To use add the following to your project .hg/hgrc for each
    project you want to check, or to your user hgrc to apply to all projects.

    [hooks]
    pretxncommit.fogbugz = python:fogbugz.pretxncommithook
    """
    hg_commit_message = repo['tip'].description()
    commit_has_bugid = _commit_regex.match(hg_commit_message) is not None

    match = _branch_regex.match(repo['tip'].branch())
    if match:
        hg_commit_message = hg_commit_message + ' BugID:'+ match.groups()[1]
            #hg_commit_message needs to be escaped for characters like >
        os.system('echo ' + hg_commit_message + ' > .hg/commit.save')

На немного несвязанной ноте, если кто-то из команды Fogbugz / Kiln увидит это ... пожалуйста, обновите ваше программное обеспечение, чтобы прочитать имя ветви, мне не нужно ставить BugID: x при каждом проклятом коммите. Прежде всего, это напрасная трата моего времени. Во-вторых, если идентификатор дела введен неправильно, он не будет отображаться в сообщении об ошибках без особых проблем. Многие разработчики используют ветки для каждой ошибки / системы функций. Это политика компании, в которой я работаю. Fogbugz отстой.

Это не для использования человеком. Fogbugz, наш трекер ошибок, связывает фиксации с ошибками, читая BugID: x или case y в описании фиксации. Да, это смешно, что мне это даже нужно. Keyo
У меня нет доступа к серверам fogbugz. Keyo
Ртутная интеграция FogBugz использует хук группы изменений, чтобы вставить соответствующую информацию в FogBugz. Вы можете изменить это, чтобы получить идентификатор случая FogBugz из имени ветви, а не из сообщения фиксации. Конечно, вам придется постоянно обновлять свою группу изменений, если вы обновляете свою версию FogBugz. Peter Graham
Из любопытства: зачем тебе это? Вы всегда можете получить название ветви, к которой принадлежит коммит. PS: о, это требование Килна: -S Так странно zerkms

Ваш Ответ

2   ответа
6

pretxncommit Хук выполняется в точке, где вы больше ничего не можете изменить. И в этот момент вы также не можете получить сообщение фиксации, поскольку оно не установлено ни для одного доступного объекта контекста.

repo['tip'].description() не относится к фиксируемому журналу изменений, но к уже принятому старому совету, который будетrepo[None], но, как показали некоторые поиски в источнике, это не тот же самый контекстный объект, который сохраняется, поэтому нет смысла менять его.

единственный способ, которым я мог бы найти, - это использовать более ранний хук - какprecommit - и обезьянаcommitctx метод репозитория вроде этого:

def precommit_hook(repo, **kwargs):

    # keep a copy of repo.commitctx
    commitctx = repo.commitctx

    def updatectx(ctx, error):

        # check if `ctx.branch()` matches ...

        # update commit text
        ctx._text += " ... additional text"

        # call original
        return commitctx(ctx, error)

    # monkeypatch the commit method
    repo.commitctx = updatectx

таким образом, cou может получить доступ к объекту контекста непосредственно перед его фиксацией.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Keyo
5

но на самом деле есть встроенный способ сделать это, если вы хотите написать свое собственное расширение (этодействительно легконемного больше, чем просто написание функциональности хуков, которую вы хотели написать в любом случае).

& Quot; Право & quot; способ сделать это, чтобы создать подкласс хранилища вreposetup, как показано в документацииmercurial.extensions.wrapfunction (потому что получаетсяwrapfunction это не правильный способ сделать это для репозиториев:

Wrapping methods of the repository object is not recommended since
it conflicts with extensions that extend the repository by
subclassing. All extensions that need to extend methods of
localrepository should use this subclassing trick: namely,
reposetup() should look like

  def reposetup(ui, repo):
      class myrepo(repo.__class__):
          def whatever(self, *args, **kwargs):
              [...extension stuff...]
              super(myrepo, self).whatever(*args, **kwargs)
              [...extension stuff...]

      repo.__class__ = myrepo

Так, например, ваше расширение будет выглядеть так (урезано):

#!/usr/bin/python
import re
import mercurial, sys, os

_branch_regex = re.compile('(feature|bug|case|bugid|fogbugz)_(\d+)')
_commit_regex = re.compile(r'\b(?P<case>(review|case|bug[zs]?(\s| )*(id)?:?)s?(\s| )*([#:; ]| )+)((([ ,:;#]|and)*)(?P<bugid>\d+))+',re.I)

#One of mercurial's callbacks for extensions. This is where you
# you want to subclass repo to add your functionality.
def reposetup(ui, repo):

    #Create a derived class that actually does what you want.
    class myrepo(repo.__class__):
        def commitctx(self, ctx, *args, **kwargs):
            match = _branch_regex.match(ctx.branch())
            if match:
                ctx._text += ' BugID:'+ match.groups()[1]

    #Make sure to actually use the new subclass.
    repo.__class__ = myrepo

### Finish off the extensions stuff

# We aren't adding any commands to hg.
cmdtables = {}

#List of known compatible versions of hg.
testedwith = '2.7.1'

Я проверил это, и он отлично работает. Вы можете использовать расширение, сохранив его в файле Python, скажем,/some-path/fogbugz.pyи добавив его подextensions группа в вашей hgrc:

[extensions]
fogbugz = /some-path/fogbugz.py

Похожие вопросы