File: compat.py

package info (click to toggle)
hg-git 0.8.12-1%2Bdeb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 876 kB
  • sloc: python: 6,248; sh: 102; makefile: 32
file content (206 lines) | stat: -rw-r--r-- 6,157 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
from mercurial import (
    bookmarks,
    context,
    phases,
    templatekw,
    url,
    util as hgutil,
)

try:
    from mercurial import encoding
    hfsignoreclean = encoding.hfsignoreclean
except AttributeError:
    # compat with hg 3.2.1 and earlier, which doesn't have
    # hfsignoreclean (This was borrowed wholesale from hg 3.2.2.)
    _ignore = [unichr(int(x, 16)).encode("utf-8") for x in
               "200c 200d 200e 200f 202a 202b 202c 202d 202e "
               "206a 206b 206c 206d 206e 206f feff".split()]
    # verify the next function will work
    assert set([i[0] for i in _ignore]) == set(["\xe2", "\xef"])

    def hfsignoreclean(s):
        """Remove codepoints ignored by HFS+ from s.

        >>> hfsignoreclean(u'.h\u200cg'.encode('utf-8'))
        '.hg'
        >>> hfsignoreclean(u'.h\ufeffg'.encode('utf-8'))
        '.hg'
        """
        if "\xe2" in s or "\xef" in s:
            for c in _ignore:
                s = s.replace(c, '')
        return s

try:
    from mercurial import vfs as vfsmod
    hgvfs = vfsmod.vfs
except ImportError:
    # vfsmod was extracted in hg 4.2
    from mercurial import scmutil
    hgvfs = scmutil.vfs

try:
    from mercurial.utils import procutil, stringutil
    sshargs = procutil.sshargs
    shellquote = procutil.shellquote
    quotecommand = procutil.quotecommand
    binary = stringutil.binary
except ImportError:
    # these were moved in 4.6
    sshargs = hgutil.sshargs
    shellquote = hgutil.shellquote
    quotecommand = hgutil.quotecommand
    binary = hgutil.binary


def gitvfs(repo):
    """return a vfs suitable to read git related data"""
    # Mercurial >= 3.3:  repo.shared()
    if repo.sharedpath != repo.path:
        return hgvfs(repo.sharedpath)
    else:
        return repo.vfs


def passwordmgr(ui):
    try:
        realm = hgutil.urlreq.httppasswordmgrwithdefaultrealm()
        return url.passwordmgr(ui, realm)
    except (TypeError, AttributeError):
        # compat with hg < 3.9
        return url.passwordmgr(ui)

# bookmarks.setcurrent was renamed to activate in hg 3.5
if hgutil.safehasattr(bookmarks, 'activate'):
    activatebookmark = bookmarks.activate
else:
    activatebookmark = bookmarks.setcurrent

def advancephaseboundary(repo, tr, targetphase, nodes):
    # hg 3.2 - advanceboundary uses transaction
    try:
        phases.advanceboundary(repo, tr, targetphase, nodes)
    except TypeError:
        phases.advanceboundary(repo, targetphase, nodes)

# hg 4.3 - osutil moved, but mercurial.util re-exports listdir
if hgutil.safehasattr(hgutil, 'listdir'):
    listdir = hgutil.listdir
else:
    from mercurial import osutil
    listdir = osutil.listdir


try:
    import dulwich.client
    FetchPackResult = dulwich.client.FetchPackResult
    read_pkt_refs = dulwich.client.read_pkt_refs
except (AttributeError, ImportError):
    # older dulwich doesn't return the symref where remote HEAD points, so we
    # monkey patch it here
    from dulwich.errors import GitProtocolError
    from dulwich.protocol import extract_capabilities

    class FetchPackResult(object):
        """Result of a fetch-pack operation.
        :var refs: Dictionary with all remote refs
        :var symrefs: Dictionary with remote symrefs
        :var agent: User agent string
        """

        def __init__(self, refs, symrefs, agent):
            self.refs = refs
            self.symrefs = symrefs
            self.agent = agent

    def read_pkt_refs(proto):
        server_capabilities = None
        refs = {}
        # Receive refs from server
        for pkt in proto.read_pkt_seq():
            (sha, ref) = pkt.rstrip('\n').split(None, 1)
            if sha == 'ERR':
                raise GitProtocolError(ref)
            if server_capabilities is None:
                (ref, server_capabilities) = extract_capabilities(ref)
                symref = 'symref=HEAD:'
                for cap in server_capabilities:
                    if cap.startswith(symref):
                        sha = cap.replace(symref, '')
            refs[ref] = sha

        if len(refs) == 0:
            return None, set([])
        return refs, set(server_capabilities)


def memfilectx(repo, changectx, path, data, islink=False,
               isexec=False, copied=None):
    # Different versions of mercurial have different parameters to
    # memfilectx.  Try them from newest to oldest.
    args_to_try = (
        (repo, changectx, path, data),  # hg 4.5+
        (repo, path, data),             # hg 3.1 - 4.5
        (path, data),                   # hg < 3.1
    )
    for args in args_to_try:
        try:
            return context.memfilectx(*args,
                                      islink=islink,
                                      isexec=isexec,
                                      copied=copied)
        except TypeError as ex:
            last_ex = ex
    raise last_ex


CONFIG_DEFAULTS = {
    'git': {
        'authors': None,
        'blockdotgit': True,
        'blockdothg': True,
        'branch_bookmark_suffix': None,
        'debugextrainmessage': False,   # test only -- do not document this!
        'findcopiesharder': False,
        'intree': None,
        'mindate': None,
        'public': list,
        'renamelimit': 400,
        'similarity': 0,
    },
    'hggit': {
        'mapsavefrequency': 0,
        'usephases': False,
    }
}

hasconfigitems = False


def registerconfigs(configitem):
    global hasconfigitems
    hasconfigitems = True
    for section, items in CONFIG_DEFAULTS.iteritems():
        for item, default in items.iteritems():
            configitem(section, item, default=default)


def config(ui, subtype, section, item):
    if subtype == 'string':
        subtype = ''
    getconfig = getattr(ui, 'config' + subtype)
    if hasconfigitems:
        return getconfig(section, item)
    return getconfig(section, item, CONFIG_DEFAULTS[section][item])


class templatekeyword(object):
    def __init__(self):
        self._table = {}

    def __call__(self, name):
        def decorate(func):
            templatekw.keywords.update({name: func})
            return func
        return decorate