2012-04-29 11 views
8

Editar Realizó este enganche básico para evitar el nombre de la rama & cometer mensaje ID de error ID. https://gist.github.com/2583189Mercurial Hook: cambie un mensaje de confirmación precompromiso

Así que básicamente la idea es que el gancho debe agregar "BugID: xyz" al final de los mensajes de confirmación si el nombre de la rama es como bug_123 o feature_123. Sin embargo, tengo problemas para descubrir cómo hacerlo, ya que la mayoría de los ejemplos de personas con compromiso previo no desean modificar la descripción del conjunto de cambios.

Esto es lo que tengo hasta ahora. Actualiza .hg/commit.save con el mensaje correcto, pero este mensaje nunca se transfiere a la confirmación. Sin embargo, se muestra en el cuadro de mensaje predeterminado (tortoisehg) del siguiente compromiso. Quizás pretxncommit no es el gancho correcto?

¿Podría utilizar un enganche precommitido, leer el archivo commit.save y repo ['tip']. Branch() y cambiar que, de ser así, ¿de dónde sacaría el nombre de la rama?

# 
# 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') 

En otro orden de no relacionado, si alguien del equipo FogBugz/horno ve esto ... por favor, actualice su software para leer el nombre de la sucursal, que no debería necesitar para poner un BUGID: x en cada maldito comprometerse . Antes que nada, desperdicia mi tiempo. En segundo lugar, si la Id. De un caso se escribe incorrectamente, no aparecerá en el error sin muchos problemas. Muchos desarrolladores usan una rama por sistema de error/función. Es la política de la compañía donde trabajo. Fogbugz apesta.

+0

Por curiosidad: ¿por qué necesita eso? Siempre puede recuperar el nombre de la rama al que pertenece la confirmación. PD: oh, es el requisito de horno: -S Tan extraño – zerkms

+0

No es para uso humano. Fogbugz, nuestro asociado de seguimiento de errores se compromete con los errores leyendo el Id. De error: x o caso y en la descripción del compromiso. Sí, es ridículo que incluso lo necesite. – Keyo

+0

La integración mercurial de FogBugz usa un gancho changegroup para insertar la información relevante en FogBugz. Posiblemente podría modificar eso para obtener el id. De caso de FogBugz del nombre de la sucursal en lugar del mensaje de confirmación. Por supuesto, debería mantener actualizado su grupo de cambios si actualiza su versión de FogBugz. –

Respuesta

6

Creo que el problema aquí es que el gancho pretxncommit se ejecuta en un punto donde ya no se puede cambiar nada. Y tampoco puede obtener realmente el mensaje de confirmación en ese punto, porque no está establecido en ningún objeto de contexto accesible.

repo['tip'].description() no se refiere al registro de cambios comprometido sino al consejo anterior ya cometido, que sería repo[None], pero como algunos de los que están en la fuente revelaron que no es el mismo objeto de contexto que persiste, no tiene sentido cambiar eso.

la única manera que podría encontrar sería el uso de un gancho antes - como precommit - y monkeypatch el método commitctx del repositorio de la siguiente manera:

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 

esta manera COU puede acceder al objeto de contexto justo antes de que sea comprometido.

+0

Se ve bien. Estaba intentando usar precommit + .hg/commit.save para hacer esto. Te dejaré saber cómo va. – Keyo

+0

esto es ciertamente astuto pero me ayudó –

5

La respuesta de mata es ingeniosa, pero de hecho hay una forma integrada de hacerlo si estás dispuesto a escribir tu propia extensión (es really easy, poco más que escribir la funcionalidad de gancho que querías escribir de todos modos).

la forma "correcta" de hacerlo es a subclase el repositorio en reposetup, como se muestra en la cadena de documentación de mercurial.extensions.wrapfunction (porque resulta wrapfunction no es la forma correcta de hacerlo para los repos:

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 

Así, por ejemplo, su extensión se vería así (simplificada):

#!/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' 

he probado esto y funciona bienPuede utilizar la extensión guardándolo en un archivo de Python, por ejemplo /some-path/fogbugz.py, y añadiendo que en el grupo extensions en su hgrc:

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