Change-Id: I901c023f707a0223af673c217c65434e26e2ab1f Reviewed-on: https://cl.tvl.fyi/c/depot/+/568 Reviewed-by: lukegb <lukegb@tvl.fyi>
		
			
				
	
	
		
			63 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			63 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""Bizarre hacks to make Gerrit better."""
 | 
						|
 | 
						|
import collections
 | 
						|
import re
 | 
						|
import random
 | 
						|
import mercurial
 | 
						|
 | 
						|
_ = mercurial.i18n._
 | 
						|
 | 
						|
cmdtable = {}
 | 
						|
command = mercurial.registrar.command(cmdtable)
 | 
						|
 | 
						|
testedwith = '5.3.1'
 | 
						|
 | 
						|
_changeid_regex = re.compile(b'^Change-Id: (I.*)$', re.M)
 | 
						|
 | 
						|
def random_hash():
 | 
						|
    """Returns a random SHA1-like hex string."""
 | 
						|
    return b"%040x" % random.getrandbits(160)
 | 
						|
 | 
						|
def reposetup(ui, repo):
 | 
						|
 | 
						|
    class GerritRepo(repo.__class__):
 | 
						|
        def commitctx(self, ctx, *args, **kwargs):
 | 
						|
            match = _changeid_regex.search(ctx._text)
 | 
						|
            if not match:
 | 
						|
                ctx._text = ctx._text.rstrip(b'\n')
 | 
						|
                ctx._text += b'\n\nChange-Id: I' + random_hash()
 | 
						|
            return super().commitctx(ctx, *args, **kwargs)
 | 
						|
 | 
						|
    repo.__class__ = GerritRepo
 | 
						|
 | 
						|
 | 
						|
@command(b'gerrit-obsolete', [], _(b'[options]'))
 | 
						|
def gerritobsolete(ui, repo, **opts):
 | 
						|
    """Mark draft commits as obsolete by public commits based on Gerrit Change-Id tag."""
 | 
						|
    if repo.obsstore.readonly:
 | 
						|
        ui.error(b'obsstore is readonly')
 | 
						|
        return
 | 
						|
    changesets = collections.defaultdict(set)
 | 
						|
    drafts = set()
 | 
						|
    for draft in repo.set('draft() - obsolete()'):
 | 
						|
        match = _changeid_regex.search(draft.description())
 | 
						|
        if not match:
 | 
						|
            continue
 | 
						|
        changesets[match.groups()[0]].add(draft)
 | 
						|
        drafts.add(draft)
 | 
						|
    if not drafts:
 | 
						|
        return
 | 
						|
    publicparent = next(repo.set(
 | 
						|
        b'ancestor((public() and bookmark("canon")), %s)' % (
 | 
						|
            b', '.join(x.hex() for x in drafts))))
 | 
						|
    megare = b're:(?ms)^Change-Id: (%s)$' % (b'|'.join(changesets.keys()),)
 | 
						|
    markers = []
 | 
						|
    for public in repo.set('(%s..(public() and canon)) and desc(%s)', publicparent, megare):
 | 
						|
        match = _changeid_regex.search(public.description())
 | 
						|
        if not match:
 | 
						|
            continue
 | 
						|
        drafts = changesets[match.groups()[0]]
 | 
						|
        if not drafts:
 | 
						|
            continue
 | 
						|
        markers.append((tuple(drafts), (public,)))
 | 
						|
    mercurial.obsolete.createmarkers(repo, markers, operation=b'gerrit-obsolete')
 |