python mercurial mercurial-hook

python - Mercurial Hook: cambie un mensaje de confirmación antes de confirmar



mercurial-hook (2)

Creo que el problema aquí es que el pretxncommit se ejecuta en un punto en el que 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 hace referencia al registro de cambios que se ha confirmado, sino al antiguo consejo ya confirmado, que sería repo[None] , pero a medida que se profundiza en la fuente, se revela que no es el mismo objeto de contexto que se está persistió, así que no tiene sentido cambiarlo.

la única forma que podría encontrar sería usar un precompilado commitctx parecido a un enganche y aplicar 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

De esta forma, cou puede acceder al objeto de contexto justo antes de comprometerse.

Editar Hecho este gancho básico para evitar el nombre de la rama y cometer error de identificación de mensaje ID. https://gist.github.com/2583189

Entonces, 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?

¿Puedo usar un enlace precommitido, leer los archivos commit.save y repo [''tip'']. Branch () y cambiar eso, en caso afirmativo, de dónde obtendrí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 una nota poco relacionada, si alguien del equipo de Fogbugz / Kiln ve esto ... por favor actualice su software para leer el nombre de la rama, no debería necesitar poner un BugID: x en cada maldito commit. Antes que nada, desperdicia mi tiempo. En segundo lugar, si la Id. Del caso se escribe de manera incorrecta, 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.


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

La forma "correcta" de hacer esto es subclasificar el repositorio en el reposetup , como se muestra en el docstring de mercurial.extensions.wrapfunction (porque resulta que la función de wrapfunction no es la forma correcta de hacerlo para los repositorios):

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í (despojado):

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

Lo he probado y funciona bien. Puede usar la extensión guardándola en un archivo python, digamos /some-path/fogbugz.py y agregándolo debajo del grupo de extensions en su hgrc:

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