1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
"""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')
|