Mercurial Hook – cambia un mensaje de confirmación antes de confirmar

Editar Realice este enlace básico para evitar errores de coincidencia entre el nombre de la twig y el mensaje ID de error. https://gist.github.com/2583189

Básicamente, la idea es que el enlace debe agregar “BugID: xyz” al final de los mensajes de confirmación si el nombre de la twig es como bug_123, o feature_123. Sin embargo, estoy teniendo problemas para descubrir cómo hacer esto, ya que la mayoría de los ejemplos de personas pretexncommit no quieren mutar 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) de la siguiente confirmación. Tal vez pretxncommit no es el gancho derecho?

¿Puedo usar un enlace previo, leer el archivo commit.save y repo [‘tip’]. Branch () y cambiarlo? De ser así, ¿de dónde obtendré el nombre de la twig?

# # 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(review|case|bug[zs]?(\s| )*(id)?:?)s?(\s| )*([#:; ]| )+)((([ ,:;#]|and)*)(?P\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 una nota no relacionada, si alguien del equipo de Fogbugz / Kiln ve esto … por favor, actualice su software para leer el nombre de la sucursal, no debería tener que poner un BugID: x en cada maldita confirmación. En primer lugar, desperdicia mi tiempo. En segundo lugar, si el ID de caso se escribe incorrectamente, no aparecerá en el error sin mucho lío. Muchos desarrolladores utilizan una twig por sistema de características / errores. Es política de la empresa donde trabajo. Fogbugz apesta.

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

repo['tip'].description() no se refiere al registro de cambios que se está cometiendo, sino a un tip antiguo ya confirmado, eso sería repo[None] , pero como algunos descubrieron la fuente, no es el mismo objeto de contexto que está siendo Persistió, así que no tiene sentido cambiarlo.

La única forma que podría encontrar sería usar un enlace anterior (como precommit) y monkeypatch el método commitctx del repository de esta 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 

De esta manera, cou puede acceder al objeto de contexto justo antes de que se confirme.

La respuesta de mata es inteligente, pero en realidad hay una forma integrada de hacerlo si está dispuesto a escribir su propia extensión (es realmente fácil , poco más que simplemente escribir la funcionalidad de enlace que quería escribir de todos modos).

La forma “correcta” de hacer esto es subclasificar el repository en reposetup , como se muestra en la cadena de documentos de mercurial.extensions.wrapfunction (porque resulta que la función wrapfunction no es la forma correcta de hacerlo para los repositorys:

 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 

Entonces, por ejemplo, su extensión se vería así (reducida):

 #!/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(review|case|bug[zs]?(\s| )*(id)?:?)s?(\s| )*([#:; ]| )+)((([ ,:;#]|and)*)(?P\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 bien. Puede usar la extensión guardándola en un archivo python, diga /some-path/fogbugz.py , y agregándola al grupo de extensions en su hgrc:

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