8

編集ブランチ名とコミットメッセージのバグIDの不一致を防ぐために、この基本的なフックを作成しました。https://gist.github.com/2583189

基本的には、ブランチ名が bug_123 や feature_123 のような場合、フックはコミット メッセージの末尾に「BugID:xyz」を追加する必要があります。しかし、pretxncommit の人々のほとんどの例は変更セットの説明を変更したくないため、これを行う方法を見つけるのに問題があります。

これは私がこれまでに持っているものです。正しいメッセージで .hg/commit.save を更新しますが、このメッセージは決してコミットに転送されません。ただし、次のコミットのデフォルトのメッセージ ボックス (tortoisehg) に表示されます。おそらく pretxncommit は適切なフックではありませんか?

precommit フックを使用して、commit.save および repo['tip'].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 を付ける必要はありません。まず第一に、それは私の時間を無駄にします。第 2 に、ケース ID が正しく入力されていない場合、多くの操作を行わないとバグに表示されません。多くの開発者は、バグ/機能システムごとにブランチを使用しています。私が働いている会社の方針です。Fogbugzは最悪です。

4

2 に答える 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

このようにして、コミットされる直前にコンテキスト オブジェクトにアクセスできます。

于 2012-05-06T00:19:32.017 に答える
5

mata の答えは賢いですが、独自の拡張機能を作成する場合は、実際にこれを行う組み込みの方法があります (とにかく書きたいフック機能を書くだけで、本当に簡単です)。

これを行う「正しい」方法は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 ファイルに保存し、hgrc/some-path/fogbugz.pyのグループの下に追加することで使用できます。extensions

[extensions]
fogbugz = /some-path/fogbugz.py
于 2013-10-29T14:56:19.663 に答える