File: revsets.py

package info (click to toggle)
hg-git 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 1,244 kB
  • sloc: python: 8,702; sh: 185; makefile: 23
file content (90 lines) | stat: -rw-r--r-- 2,740 bytes parent folder | download
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from mercurial import error
from mercurial import exthelper
from mercurial import revset
from mercurial.i18n import _
from mercurial.node import bin, hex
from mercurial.utils import stringutil

eh = exthelper.exthelper()


@eh.revsetpredicate(b'fromgit')
def revset_fromgit(repo, subset, x):
    '''``fromgit()``
    Select changesets that originate from Git.
    '''
    revset.getargs(x, 0, 0, b"fromgit takes no arguments")
    git = repo.githandler
    node = repo.changelog.node
    return revset.baseset(
        r for r in subset if git.map_git_get(hex(node(r))) is not None
    )


@eh.revsetpredicate(b'gitnode')
def revset_gitnode(repo, subset, x):
    '''``gitnode(hash)``
    Select the changeset that originates in the given Git revision. The hash
    may be abbreviated: `gitnode(a5b)` selects the revision whose Git hash
    starts with `a5b`. Aborts if multiple changesets match the abbreviation.
    '''
    args = revset.getargs(x, 1, 1, b"gitnode takes one argument")
    rev = revset.getstring(args[0], b"the argument to gitnode() must be a hash")
    git = repo.githandler
    node = repo.changelog.node

    def matches(r):
        gitnode = git.map_git_get(hex(node(r)))
        if gitnode is None:
            return False
        return gitnode.startswith(rev)

    result = revset.baseset(r for r in subset if matches(r))
    if 0 <= len(result) < 2:
        return result

    raise error.AmbiguousPrefixLookupError(
        rev,
        git.map_file,
        _(b'ambiguous identifier'),
    )


@eh.revsetpredicate(b'gittag')
def revset_gittag(repo, subset, x):
    """``gittag([name])``

    The specified Git tag by name, or all revisions tagged with Git if
    no name is given.

    Pattern matching is supported for `name`. See
    :hg:`help revisions.patterns`.

    """
    # mostly copied from tag() mercurial/revset.py

    # i18n: "tag" is a keyword
    args = revset.getargs(x, 0, 1, _(b"tag takes one or no arguments"))
    cl = repo.changelog
    git = repo.githandler

    if args:
        pattern = revset.getstring(
            args[0],
            # i18n: "tag" is a keyword
            _(b'the argument to tag must be a string'),
        )
        kind, pattern, matcher = stringutil.stringmatcher(pattern)
        if kind == b'literal':
            # avoid resolving all tags
            tn = git.tags.get(pattern, None)
            if tn is None:
                raise error.RepoLookupError(
                    _(b"git tag '%s' does not exist") % pattern
                )
            s = {repo[bin(tn)].rev()}
        else:
            s = {cl.rev(bin(n)) for t, n in git.tags.items() if matcher(t)}
    else:
        s = {cl.rev(bin(n)) for t, n in git.tags.items()}
    return subset & s