/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
1
# Copyright (C) 2007 Canonical Ltd
0.252.32 by Jelmer Vernooij
update copyright
2
# Copyright (C) 2008-2010 Jelmer Vernooij <jelmer@samba.org>
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
3
# Copyright (C) 2008 John Carr
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
"""Converters, etc for going between Bazaar and Git ids."""
20
0.200.1594 by Jelmer Vernooij
Use absolute_import everywhere.
21
from __future__ import absolute_import
22
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
23
import base64
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
24
import stat
25
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
26
from ... import (
0.200.926 by Jelmer Vernooij
Fix formatting, drop support for Bazaar < 2.0.
27
    bencode,
0.200.292 by Jelmer Vernooij
Fix formatting.
28
    errors,
29
    foreign,
0.200.490 by Jelmer Vernooij
Warn about unusual modes and escaped XML-invalid characters.
30
    trace,
0.200.292 by Jelmer Vernooij
Fix formatting.
31
    )
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
32
from ...bzr.inventory import (
0.200.292 by Jelmer Vernooij
Fix formatting.
33
    ROOT_ID,
34
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
35
from ...foreign import (
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
36
    ForeignVcs,
37
    VcsMappingRegistry,
0.200.292 by Jelmer Vernooij
Fix formatting.
38
    ForeignRevision,
39
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
40
from ...revision import (
0.200.701 by Jelmer Vernooij
Fix check in git repos.
41
    NULL_REVISION,
42
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
43
from .errors import (
0.200.1598 by Jelmer Vernooij
Print proper error when unknown fields are encountered.
44
    NoPushSupport,
45
    UnknownCommitExtra,
0.200.1640 by Jelmer Vernooij
Support HG extra 'amend_source'.
46
    UnknownMercurialCommitExtra,
0.200.1598 by Jelmer Vernooij
Print proper error when unknown fields are encountered.
47
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
48
from .hg import (
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
49
    format_hg_metadata,
50
    extract_hg_metadata,
51
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
52
from .roundtrip import (
0.252.2 by Jelmer Vernooij
Add functions for adding metadata to revision messages.
53
    extract_bzr_metadata,
0.252.4 by Jelmer Vernooij
More work on roundtripping.
54
    inject_bzr_metadata,
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
55
    CommitSupplement,
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
56
    deserialize_fileid_map,
57
    serialize_fileid_map,
0.252.2 by Jelmer Vernooij
Add functions for adding metadata to revision messages.
58
    )
0.200.309 by Jelmer Vernooij
Add XML escaping to work around serialization bug in bzr.
59
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
60
DEFAULT_FILE_MODE = stat.S_IFREG | 0644
0.200.1638 by Jelmer Vernooij
Support HG:rename-source extra fields.
61
HG_RENAME_SOURCE = "HG:rename-source"
0.200.1640 by Jelmer Vernooij
Support HG extra 'amend_source'.
62
HG_EXTRA = "HG:extra"
63
64
# This HG extra is used to indicate the commit that this commit was based on.
65
HG_EXTRA_AMEND_SOURCE = "amend_source"
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
66
0.200.1712 by Jelmer Vernooij
Add file_id prefix.
67
FILE_ID_PREFIX = b'git:'
68
0.206.1 by Jelmer Vernooij
Use foreign utility functions.
69
0.200.150 by Jelmer Vernooij
Abstract away file id generation.
70
def escape_file_id(file_id):
0.200.1419 by Jelmer Vernooij
Escape/unescape ^L characters.
71
    return file_id.replace('_', '__').replace(' ', '_s').replace('\x0c', '_c')
0.200.150 by Jelmer Vernooij
Abstract away file id generation.
72
73
74
def unescape_file_id(file_id):
0.200.390 by Jelmer Vernooij
Fix file id unescape function when there are other underscores in the file id.
75
    ret = []
76
    i = 0
77
    while i < len(file_id):
78
        if file_id[i] != '_':
79
            ret.append(file_id[i])
80
        else:
81
            if file_id[i+1] == '_':
82
                ret.append("_")
83
            elif file_id[i+1] == 's':
84
                ret.append(" ")
0.200.1419 by Jelmer Vernooij
Escape/unescape ^L characters.
85
            elif file_id[i+1] == 'c':
86
                ret.append("\x0c")
0.200.390 by Jelmer Vernooij
Fix file id unescape function when there are other underscores in the file id.
87
            else:
0.200.1712 by Jelmer Vernooij
Add file_id prefix.
88
                raise ValueError("unknown escape character %s" %
0.200.826 by Jelmer Vernooij
Fix some long lines.
89
                    file_id[i+1])
0.200.390 by Jelmer Vernooij
Fix file id unescape function when there are other underscores in the file id.
90
            i += 1
91
        i += 1
92
    return "".join(ret)
0.200.150 by Jelmer Vernooij
Abstract away file id generation.
93
94
0.200.376 by Jelmer Vernooij
Make sure author and committer names pushed to git contain < and >, otherwise the git parser barfs.
95
def fix_person_identifier(text):
96
    if "<" in text and ">" in text:
0.200.1625 by Jelmer Vernooij
Cope with missing space before <
97
        if not " <" in text and text.count("<") == 1:
98
            text = text.replace("<", " <")
0.200.376 by Jelmer Vernooij
Make sure author and committer names pushed to git contain < and >, otherwise the git parser barfs.
99
        return text
100
    return "%s <%s>" % (text, text)
101
102
0.200.490 by Jelmer Vernooij
Warn about unusual modes and escaped XML-invalid characters.
103
def warn_escaped(commit, num_escaped):
104
    trace.warning("Escaped %d XML-invalid characters in %s. Will be unable "
105
                  "to regenerate the SHA map.", num_escaped, commit)
106
107
108
def warn_unusual_mode(commit, path, mode):
0.200.826 by Jelmer Vernooij
Fix some long lines.
109
    trace.mutter("Unusual file mode %o for %s in %s. Storing as revision "
110
                 "property. ", mode, path, commit)
0.200.490 by Jelmer Vernooij
Warn about unusual modes and escaped XML-invalid characters.
111
112
0.206.1 by Jelmer Vernooij
Use foreign utility functions.
113
class BzrGitMapping(foreign.VcsMapping):
0.200.97 by Jelmer Vernooij
use mapping object.
114
    """Class that maps between Git and Bazaar semantics."""
115
    experimental = False
116
0.200.915 by Jelmer Vernooij
Cope with the fact that the old format didn't export file ids.
117
    BZR_FILE_IDS_FILE = None
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
118
0.200.915 by Jelmer Vernooij
Cope with the fact that the old format didn't export file ids.
119
    BZR_DUMMY_FILE = None
0.252.26 by Jelmer Vernooij
Add is_control_file method to BzrGitMapping.
120
0.200.1328 by Jelmer Vernooij
More test fixes.
121
    def is_special_file(self, filename):
122
        return (filename in (self.BZR_FILE_IDS_FILE, self.BZR_DUMMY_FILE))
123
0.200.198 by Jelmer Vernooij
Cope with move of show_foreign_revid.
124
    def __init__(self):
0.200.1263 by Jelmer Vernooij
Fix foreign_vcs_git.
125
        super(BzrGitMapping, self).__init__(foreign_vcs_git)
0.200.198 by Jelmer Vernooij
Cope with move of show_foreign_revid.
126
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
127
    def __eq__(self, other):
0.200.1020 by Jelmer Vernooij
Store testament-sha1 in metadata.
128
        return (type(self) == type(other) and
0.200.726 by Jelmer Vernooij
Factor out conversion of branch names to refs.
129
                self.revid_prefix == other.revid_prefix)
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
130
131
    @classmethod
132
    def revision_id_foreign_to_bzr(cls, git_rev_id):
0.200.97 by Jelmer Vernooij
use mapping object.
133
        """Convert a git revision id handle to a Bazaar revision id."""
0.200.891 by Jelmer Vernooij
Use ZERO_SHA constant where possible.
134
        from dulwich.protocol import ZERO_SHA
135
        if git_rev_id == ZERO_SHA:
0.200.769 by Jelmer Vernooij
Cope with open_branch() actually checking whether there is a branch present.
136
            return NULL_REVISION
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
137
        return "%s:%s" % (cls.revid_prefix, git_rev_id)
0.200.97 by Jelmer Vernooij
use mapping object.
138
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
139
    @classmethod
140
    def revision_id_bzr_to_foreign(cls, bzr_rev_id):
0.200.97 by Jelmer Vernooij
use mapping object.
141
        """Convert a Bazaar revision id to a git revision id handle."""
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
142
        if not bzr_rev_id.startswith("%s:" % cls.revid_prefix):
143
            raise errors.InvalidRevisionId(bzr_rev_id, cls)
144
        return bzr_rev_id[len(cls.revid_prefix)+1:], cls()
0.200.97 by Jelmer Vernooij
use mapping object.
145
0.200.150 by Jelmer Vernooij
Abstract away file id generation.
146
    def generate_file_id(self, path):
0.200.297 by Jelmer Vernooij
Cope with non-ascii characters in filenames (needs a test..).
147
        # Git paths are just bytestrings
148
        # We must just hope they are valid UTF-8..
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
149
        if path == "":
150
            return ROOT_ID
0.200.973 by Jelmer Vernooij
Add tests for generate_file_id.
151
        if type(path) is unicode:
152
            path = path.encode("utf-8")
0.200.1712 by Jelmer Vernooij
Add file_id prefix.
153
        return FILE_ID_PREFIX + escape_file_id(path)
0.200.150 by Jelmer Vernooij
Abstract away file id generation.
154
0.252.26 by Jelmer Vernooij
Add is_control_file method to BzrGitMapping.
155
    def is_control_file(self, path):
156
        return path in (self.BZR_FILE_IDS_FILE, self.BZR_DUMMY_FILE)
157
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
158
    def parse_file_id(self, file_id):
159
        if file_id == ROOT_ID:
160
            return ""
0.200.1712 by Jelmer Vernooij
Add file_id prefix.
161
        if not file_id.startswith(FILE_ID_PREFIX):
162
            raise ValueError
163
        return unescape_file_id(file_id[len(FILE_ID_PREFIX):])
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
164
0.252.31 by Jelmer Vernooij
Properly escape revids when using them in ref names.
165
    def revid_as_refname(self, revid):
166
        import urllib
167
        return "refs/bzr/%s" % urllib.quote(revid)
168
0.200.546 by Jelmer Vernooij
Add more docstrings, support storing unusual file modes.
169
    def import_unusual_file_modes(self, rev, unusual_file_modes):
170
        if unusual_file_modes:
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
171
            ret = [(path, unusual_file_modes[path])
172
                   for path in sorted(unusual_file_modes.keys())]
0.200.549 by Jelmer Vernooij
Fix storing of unusual file modes.
173
            rev.properties['file-modes'] = bencode.bencode(ret)
0.200.546 by Jelmer Vernooij
Add more docstrings, support storing unusual file modes.
174
0.200.547 by Jelmer Vernooij
Support getting unusual file modes out of revision properties.
175
    def export_unusual_file_modes(self, rev):
176
        try:
0.200.894 by Jelmer Vernooij
Simplify formatting a bit.
177
            file_modes = rev.properties['file-modes']
0.200.547 by Jelmer Vernooij
Support getting unusual file modes out of revision properties.
178
        except KeyError:
179
            return {}
0.200.894 by Jelmer Vernooij
Simplify formatting a bit.
180
        else:
181
            return dict([(self.generate_file_id(path), mode) for (path, mode) in bencode.bdecode(file_modes.encode("utf-8"))])
0.200.547 by Jelmer Vernooij
Support getting unusual file modes out of revision properties.
182
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
183
    def _generate_git_svn_metadata(self, rev, encoding):
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
184
        try:
0.200.894 by Jelmer Vernooij
Simplify formatting a bit.
185
            git_svn_id = rev.properties["git-svn-id"]
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
186
        except KeyError:
187
            return ""
0.200.894 by Jelmer Vernooij
Simplify formatting a bit.
188
        else:
189
            return "\ngit-svn-id: %s\n" % git_svn_id.encode(encoding)
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
190
0.200.638 by Jelmer Vernooij
Abstract support for hg-git metadata.
191
    def _generate_hg_message_tail(self, rev):
192
        extra = {}
193
        renames = []
0.200.639 by Jelmer Vernooij
Support renames in hg-git messages as well.
194
        branch = 'default'
0.200.638 by Jelmer Vernooij
Abstract support for hg-git metadata.
195
        for name in rev.properties:
196
            if name == 'hg:extra:branch':
197
                branch = rev.properties['hg:extra:branch']
198
            elif name.startswith('hg:extra'):
0.200.826 by Jelmer Vernooij
Fix some long lines.
199
                extra[name[len('hg:extra:'):]] = base64.b64decode(
200
                    rev.properties[name])
0.200.639 by Jelmer Vernooij
Support renames in hg-git messages as well.
201
            elif name == 'hg:renames':
0.200.826 by Jelmer Vernooij
Fix some long lines.
202
                renames = bencode.bdecode(base64.b64decode(
203
                    rev.properties['hg:renames']))
0.200.639 by Jelmer Vernooij
Support renames in hg-git messages as well.
204
            # TODO: Export other properties as 'bzr:' extras?
0.200.660 by Jelmer Vernooij
Fix encoding issues.
205
        ret = format_hg_metadata(renames, branch, extra)
206
        assert isinstance(ret, str)
207
        return ret
0.200.638 by Jelmer Vernooij
Abstract support for hg-git metadata.
208
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
209
    def _extract_git_svn_metadata(self, rev, message):
210
        lines = message.split("\n")
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
211
        if not (lines[-1] == "" and len(lines) >= 2 and lines[-2].startswith("git-svn-id:")):
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
212
            return message
0.200.652 by Jelmer Vernooij
Split out git-svn-id parser as separate function, implement ForeignGit.serialize_foreign_revid.
213
        git_svn_id = lines[-2].split(": ", 1)[1]
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
214
        rev.properties['git-svn-id'] = git_svn_id
0.200.652 by Jelmer Vernooij
Split out git-svn-id parser as separate function, implement ForeignGit.serialize_foreign_revid.
215
        (url, rev, uuid) = parse_git_svn_id(git_svn_id)
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
216
        # FIXME: Convert this to converted-from property somehow..
0.200.660 by Jelmer Vernooij
Fix encoding issues.
217
        ret = "\n".join(lines[:-2])
218
        assert isinstance(ret, str)
219
        return ret
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
220
0.200.638 by Jelmer Vernooij
Abstract support for hg-git metadata.
221
    def _extract_hg_metadata(self, rev, message):
222
        (message, renames, branch, extra) = extract_hg_metadata(message)
223
        if branch is not None:
224
            rev.properties['hg:extra:branch'] = branch
225
        for name, value in extra.iteritems():
226
            rev.properties['hg:extra:' + name] = base64.b64encode(value)
0.200.639 by Jelmer Vernooij
Support renames in hg-git messages as well.
227
        if renames:
0.200.826 by Jelmer Vernooij
Fix some long lines.
228
            rev.properties['hg:renames'] = base64.b64encode(bencode.bencode(
229
                [(new, old) for (old, new) in renames.iteritems()]))
0.200.638 by Jelmer Vernooij
Abstract support for hg-git metadata.
230
        return message
231
0.252.2 by Jelmer Vernooij
Add functions for adding metadata to revision messages.
232
    def _extract_bzr_metadata(self, rev, message):
233
        (message, metadata) = extract_bzr_metadata(message)
0.252.4 by Jelmer Vernooij
More work on roundtripping.
234
        return message, metadata
0.252.2 by Jelmer Vernooij
Add functions for adding metadata to revision messages.
235
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
236
    def _decode_commit_message(self, rev, message, encoding):
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
237
        return message.decode(encoding), CommitSupplement()
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
238
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
239
    def _encode_commit_message(self, rev, message, encoding):
240
        return message.encode(encoding)
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
241
0.252.22 by Jelmer Vernooij
Fix file id map (de)serialization.
242
    def export_fileid_map(self, fileid_map):
243
        """Export a file id map to a fileid map.
244
245
        :param fileid_map: File id map, mapping paths to file ids
246
        :return: A Git blob object
247
        """
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
248
        from dulwich.objects import Blob
249
        b = Blob()
250
        b.set_raw_chunks(serialize_fileid_map(fileid_map))
251
        return b
0.252.22 by Jelmer Vernooij
Fix file id map (de)serialization.
252
0.200.1509 by Jelmer Vernooij
Properly raise exception when pulling from git into bzr without experimental mappings.
253
    def export_commit(self, rev, tree_sha, parent_lookup, lossy,
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
254
                      verifiers):
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
255
        """Turn a Bazaar revision in to a Git commit
256
257
        :param tree_sha: Tree sha for the commit
0.200.826 by Jelmer Vernooij
Fix some long lines.
258
        :param parent_lookup: Function for looking up the GIT sha equiv of a
259
            bzr revision
0.200.1509 by Jelmer Vernooij
Properly raise exception when pulling from git into bzr without experimental mappings.
260
        :param lossy: Whether to store roundtripping information.
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
261
        :param verifiers: Verifiers info
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
262
        :return dulwich.objects.Commit represent the revision:
263
        """
264
        from dulwich.objects import Commit
265
        commit = Commit()
266
        commit.tree = tree_sha
0.200.1509 by Jelmer Vernooij
Properly raise exception when pulling from git into bzr without experimental mappings.
267
        if not lossy:
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
268
            metadata = CommitSupplement()
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
269
            metadata.verifiers = verifiers
0.252.8 by Jelmer Vernooij
Support ghost revisions while roundtripping.
270
        else:
271
            metadata = None
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
272
        parents = []
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
273
        for p in rev.parent_ids:
0.200.705 by Jelmer Vernooij
Cope with imports.
274
            try:
275
                git_p = parent_lookup(p)
276
            except KeyError:
277
                git_p = None
0.252.8 by Jelmer Vernooij
Support ghost revisions while roundtripping.
278
                if metadata is not None:
279
                    metadata.explicit_parent_ids = rev.parent_ids
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
280
            if git_p is not None:
281
                assert len(git_p) == 40, "unexpected length for %r" % git_p
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
282
                parents.append(git_p)
283
        commit.parents = parents
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
284
        try:
285
            encoding = rev.properties['git-explicit-encoding']
286
        except KeyError:
287
            encoding = rev.properties.get('git-implicit-encoding', 'utf-8')
288
        commit.encoding = rev.properties.get('git-explicit-encoding')
289
        commit.committer = fix_person_identifier(rev.committer.encode(
290
            encoding))
291
        commit.author = fix_person_identifier(
292
            rev.get_apparent_authors()[0].encode(encoding))
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
293
        commit.commit_time = long(rev.timestamp)
294
        if 'author-timestamp' in rev.properties:
295
            commit.author_time = long(rev.properties['author-timestamp'])
296
        else:
297
            commit.author_time = commit.commit_time
0.200.884 by Jelmer Vernooij
Cope with -0000 as timezone in Git commits.
298
        commit._commit_timezone_neg_utc = "commit-timezone-neg-utc" in rev.properties
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
299
        commit.commit_timezone = rev.timezone
0.200.884 by Jelmer Vernooij
Cope with -0000 as timezone in Git commits.
300
        commit._author_timezone_neg_utc = "author-timezone-neg-utc" in rev.properties
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
301
        if 'author-timezone' in rev.properties:
302
            commit.author_timezone = int(rev.properties['author-timezone'])
303
        else:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
304
            commit.author_timezone = commit.commit_timezone
0.200.1636 by Jelmer Vernooij
Some formatting fixes.
305
        commit.message = self._encode_commit_message(rev, rev.message,
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
306
            encoding)
0.252.40 by Jelmer Vernooij
Checks for roundtripping.
307
        assert type(commit.message) == str
0.252.8 by Jelmer Vernooij
Support ghost revisions while roundtripping.
308
        if metadata is not None:
0.252.4 by Jelmer Vernooij
More work on roundtripping.
309
            try:
310
                mapping_registry.parse_revision_id(rev.revision_id)
311
            except errors.InvalidRevisionId:
312
                metadata.revision_id = rev.revision_id
0.252.10 by Jelmer Vernooij
Support roundtripping custom revision properties.
313
            mapping_properties = set(
314
                ['author', 'author-timezone', 'author-timezone-neg-utc',
315
                 'commit-timezone-neg-utc', 'git-implicit-encoding',
0.252.15 by Jelmer Vernooij
Add file-modes to list of mapping properties.
316
                 'git-explicit-encoding', 'author-timestamp', 'file-modes'])
0.252.10 by Jelmer Vernooij
Support roundtripping custom revision properties.
317
            for k, v in rev.properties.iteritems():
318
                if not k in mapping_properties:
319
                    metadata.properties[k] = v
0.200.1510 by Jelmer Vernooij
Fix tests.
320
        if not lossy:
321
            if self.roundtripping:
0.200.1636 by Jelmer Vernooij
Some formatting fixes.
322
                commit.message = inject_bzr_metadata(commit.message, metadata,
0.200.1510 by Jelmer Vernooij
Fix tests.
323
                                                     encoding)
324
            else:
325
                raise NoPushSupport()
0.252.40 by Jelmer Vernooij
Checks for roundtripping.
326
        assert type(commit.message) == str
0.200.1639 by Jelmer Vernooij
Properly roundtrip HG:rename-source fields.
327
        if 'git-extra' in rev.properties:
328
            commit.extra.extend([l.split(' ', 1) for l in rev.properties['git-extra'].splitlines()])
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
329
        return commit
330
0.252.22 by Jelmer Vernooij
Fix file id map (de)serialization.
331
    def import_fileid_map(self, blob):
332
        """Convert a git file id map blob.
333
334
        :param blob: Git blob object with fileid map
335
        :return: Dictionary mapping paths to file ids
336
        """
0.252.35 by Jelmer Vernooij
Ignore control files in inventories.
337
        return deserialize_fileid_map(blob.data)
0.252.22 by Jelmer Vernooij
Fix file id map (de)serialization.
338
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
339
    def import_commit(self, commit, lookup_parent_revid):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
340
        """Convert a git commit to a bzr revision.
341
0.200.1646 by Jelmer Vernooij
Rename bzrlib to breezy.
342
        :return: a `breezy.revision.Revision` object, foreign revid and a
0.200.1021 by Jelmer Vernooij
Put testament sha1 in revisions.
343
            testament sha1
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
344
        """
345
        if commit is None:
346
            raise AssertionError("Commit object can't be None")
0.200.826 by Jelmer Vernooij
Fix some long lines.
347
        rev = ForeignRevision(commit.id, self,
348
                self.revision_id_foreign_to_bzr(commit.id))
0.252.4 by Jelmer Vernooij
More work on roundtripping.
349
        rev.git_metadata = None
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
350
        def decode_using_encoding(rev, commit, encoding):
351
            rev.committer = str(commit.committer).decode(encoding)
352
            if commit.committer != commit.author:
353
                rev.properties['author'] = str(commit.author).decode(encoding)
0.252.4 by Jelmer Vernooij
More work on roundtripping.
354
            rev.message, rev.git_metadata = self._decode_commit_message(
355
                rev, commit.message, encoding)
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
356
        if commit.encoding is not None:
357
            rev.properties['git-explicit-encoding'] = commit.encoding
358
            decode_using_encoding(rev, commit, commit.encoding)
359
        else:
360
            for encoding in ('utf-8', 'latin1'):
361
                try:
362
                    decode_using_encoding(rev, commit, encoding)
363
                except UnicodeDecodeError:
364
                    pass
365
                else:
366
                    if encoding != 'utf-8':
367
                        rev.properties['git-implicit-encoding'] = encoding
368
                    break
0.200.350 by Jelmer Vernooij
Support author_time
369
        if commit.commit_time != commit.author_time:
370
            rev.properties['author-timestamp'] = str(commit.author_time)
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
371
        if commit.commit_timezone != commit.author_timezone:
0.200.826 by Jelmer Vernooij
Fix some long lines.
372
            rev.properties['author-timezone'] = "%d" % commit.author_timezone
0.200.884 by Jelmer Vernooij
Cope with -0000 as timezone in Git commits.
373
        if commit._author_timezone_neg_utc:
374
            rev.properties['author-timezone-neg-utc'] = ""
375
        if commit._commit_timezone_neg_utc:
376
            rev.properties['commit-timezone-neg-utc'] = ""
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
377
        rev.timestamp = commit.commit_time
0.200.440 by Jelmer Vernooij
Remove silly mapping of timezones; dulwich uses offsets now as well.
378
        rev.timezone = commit.commit_timezone
0.261.5 by Jelmer Vernooij
Fix looking up of parents during fetch.
379
        rev.parent_ids = None
0.252.4 by Jelmer Vernooij
More work on roundtripping.
380
        if rev.git_metadata is not None:
0.252.6 by Jelmer Vernooij
Roundtripping support for revision ids works.
381
            md = rev.git_metadata
0.200.1021 by Jelmer Vernooij
Put testament sha1 in revisions.
382
            roundtrip_revid = md.revision_id
0.252.8 by Jelmer Vernooij
Support ghost revisions while roundtripping.
383
            if md.explicit_parent_ids:
384
                rev.parent_ids = md.explicit_parent_ids
0.252.10 by Jelmer Vernooij
Support roundtripping custom revision properties.
385
            rev.properties.update(md.properties)
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
386
            verifiers = md.verifiers
0.200.1021 by Jelmer Vernooij
Put testament sha1 in revisions.
387
        else:
388
            roundtrip_revid = None
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
389
            verifiers = {}
0.261.5 by Jelmer Vernooij
Fix looking up of parents during fetch.
390
        if rev.parent_ids is None:
391
            rev.parent_ids = tuple([lookup_parent_revid(p) for p in commit.parents])
0.200.1639 by Jelmer Vernooij
Properly roundtrip HG:rename-source fields.
392
        unknown_extra_fields = []
393
        extra_lines = []
394
        for k, v in commit.extra:
395
            if k == HG_RENAME_SOURCE:
396
                extra_lines.append(k + ' ' + v + '\n')
0.200.1640 by Jelmer Vernooij
Support HG extra 'amend_source'.
397
            elif k == HG_EXTRA:
398
                hgk, hgv = v.split(':', 1)
399
                if hgk not in (HG_EXTRA_AMEND_SOURCE, ):
400
                    raise UnknownMercurialCommitExtra(commit, hgk)
401
                extra_lines.append(k + ' ' + v + '\n')
0.200.1639 by Jelmer Vernooij
Properly roundtrip HG:rename-source fields.
402
            else:
403
                unknown_extra_fields.append(k)
404
        if unknown_extra_fields:
405
            raise UnknownCommitExtra(commit, unknown_extra_fields)
406
        if extra_lines:
407
            rev.properties['git-extra'] = ''.join(extra_lines)
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
408
        return rev, roundtrip_revid, verifiers
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
409
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
410
    def get_fileid_map(self, lookup_object, tree_sha):
411
        """Obtain a fileid map for a particular tree.
412
413
        :param lookup_object: Function for looking up an object
414
        :param tree_sha: SHA of the root tree
415
        :return: GitFileIdMap instance
416
        """
417
        try:
418
            file_id_map_sha = lookup_object(tree_sha)[self.BZR_FILE_IDS_FILE][1]
419
        except KeyError:
420
            file_ids = {}
421
        else:
422
            file_ids = self.import_fileid_map(lookup_object(file_id_map_sha))
423
        return GitFileIdMap(file_ids, self)
424
0.200.97 by Jelmer Vernooij
use mapping object.
425
0.200.190 by Jelmer Vernooij
Bless current mapping as v1.
426
class BzrGitMappingv1(BzrGitMapping):
427
    revid_prefix = 'git-v1'
428
    experimental = False
429
0.200.393 by Jelmer Vernooij
Provide __str__ implementation for mapping, fix docstring for ForeignGit.
430
    def __str__(self):
431
        return self.revid_prefix
432
0.200.190 by Jelmer Vernooij
Bless current mapping as v1.
433
434
class BzrGitMappingExperimental(BzrGitMappingv1):
0.200.104 by Jelmer Vernooij
Use bzr-foreign function names for converting between git and bzr revids.
435
    revid_prefix = 'git-experimental'
436
    experimental = True
0.200.912 by Jelmer Vernooij
Merge roundtrip support.
437
    roundtripping = True
0.200.97 by Jelmer Vernooij
use mapping object.
438
0.200.915 by Jelmer Vernooij
Cope with the fact that the old format didn't export file ids.
439
    BZR_FILE_IDS_FILE = '.bzrfileids'
440
441
    BZR_DUMMY_FILE = '.bzrdummy'
442
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
443
    def _decode_commit_message(self, rev, message, encoding):
0.200.638 by Jelmer Vernooij
Abstract support for hg-git metadata.
444
        message = self._extract_hg_metadata(rev, message)
0.200.643 by Jelmer Vernooij
Attempt to parse git-svn-id metadata.
445
        message = self._extract_git_svn_metadata(rev, message)
0.252.4 by Jelmer Vernooij
More work on roundtripping.
446
        message, metadata = self._extract_bzr_metadata(rev, message)
447
        return message.decode(encoding), metadata
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
448
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
449
    def _encode_commit_message(self, rev, message, encoding):
450
        ret = message.encode(encoding)
0.200.638 by Jelmer Vernooij
Abstract support for hg-git metadata.
451
        ret += self._generate_hg_message_tail(rev)
0.200.727 by Jelmer Vernooij
Cope with different encodings better, rather than just stripping out
452
        ret += self._generate_git_svn_metadata(rev, encoding)
0.242.1 by Jelmer Vernooij
Add support for parsing hg-git metadata in the experimental mappings.
453
        return ret
454
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
455
    def import_commit(self, commit, lookup_parent_revid):
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
456
        rev, roundtrip_revid, verifiers = super(BzrGitMappingExperimental, self).import_commit(commit, lookup_parent_revid)
0.200.642 by Jelmer Vernooij
In experimental mappings, set 'converted_revision' property.
457
        rev.properties['converted_revision'] = "git %s\n" % commit.id
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
458
        return rev, roundtrip_revid, verifiers
0.200.642 by Jelmer Vernooij
In experimental mappings, set 'converted_revision' property.
459
0.200.97 by Jelmer Vernooij
use mapping object.
460
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
461
class GitMappingRegistry(VcsMappingRegistry):
0.200.546 by Jelmer Vernooij
Add more docstrings, support storing unusual file modes.
462
    """Registry with available git mappings."""
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
463
464
    def revision_id_bzr_to_foreign(self, bzr_revid):
0.200.701 by Jelmer Vernooij
Fix check in git repos.
465
        if bzr_revid == NULL_REVISION:
0.200.892 by Jelmer Vernooij
Lazy import ZERO_SHA.
466
            from dulwich.protocol import ZERO_SHA
0.200.891 by Jelmer Vernooij
Use ZERO_SHA constant where possible.
467
            return ZERO_SHA, None
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
468
        if not bzr_revid.startswith("git-"):
469
            raise errors.InvalidRevisionId(bzr_revid, None)
470
        (mapping_version, git_sha) = bzr_revid.split(":", 1)
471
        mapping = self.get(mapping_version)
472
        return mapping.revision_id_bzr_to_foreign(bzr_revid)
473
474
    parse_revision_id = revision_id_bzr_to_foreign
475
476
477
mapping_registry = GitMappingRegistry()
0.200.1646 by Jelmer Vernooij
Rename bzrlib to breezy.
478
mapping_registry.register_lazy('git-v1', "breezy.plugins.git.mapping",
0.200.826 by Jelmer Vernooij
Fix some long lines.
479
    "BzrGitMappingv1")
480
mapping_registry.register_lazy('git-experimental',
0.200.1646 by Jelmer Vernooij
Rename bzrlib to breezy.
481
    "breezy.plugins.git.mapping", "BzrGitMappingExperimental")
0.200.1507 by Jelmer Vernooij
Add note on experimental mapping format.
482
# Uncomment the next line to enable the experimental bzr-git mappings.
483
# This will make sure all bzr metadata is pushed into git, allowing for
484
# full roundtripping later.
485
# NOTE: THIS IS EXPERIMENTAL. IT MAY EAT YOUR DATA OR CORRUPT
486
# YOUR BZR OR GIT REPOSITORIES. USE WITH CARE.
0.200.1416 by Jelmer Vernooij
Don't use experimental mapping by default.
487
#mapping_registry.set_default('git-experimental')
488
mapping_registry.set_default('git-v1')
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
489
490
491
class ForeignGit(ForeignVcs):
0.200.393 by Jelmer Vernooij
Provide __str__ implementation for mapping, fix docstring for ForeignGit.
492
    """The Git Stupid Content Tracker"""
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
493
0.243.1 by Jelmer Vernooij
Use foreign branch testing infrastructure.
494
    @property
495
    def branch_format(self):
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
496
        from .branch import GitBranchFormat
0.243.1 by Jelmer Vernooij
Use foreign branch testing infrastructure.
497
        return GitBranchFormat()
498
0.200.657 by Jelmer Vernooij
Provide repository_format attribute, as required by newer foreign VCS tests in bzrlib.
499
    @property
500
    def repository_format(self):
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
501
        from .repository import GitRepositoryFormat
0.200.657 by Jelmer Vernooij
Provide repository_format attribute, as required by newer foreign VCS tests in bzrlib.
502
        return GitRepositoryFormat()
503
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
504
    def __init__(self):
505
        super(ForeignGit, self).__init__(mapping_registry)
0.200.646 by Jelmer Vernooij
Store abbreviation in foreign branch.
506
        self.abbreviation = "git"
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
507
0.200.198 by Jelmer Vernooij
Cope with move of show_foreign_revid.
508
    @classmethod
0.200.652 by Jelmer Vernooij
Split out git-svn-id parser as separate function, implement ForeignGit.serialize_foreign_revid.
509
    def serialize_foreign_revid(self, foreign_revid):
510
        return foreign_revid
511
512
    @classmethod
0.200.198 by Jelmer Vernooij
Cope with move of show_foreign_revid.
513
    def show_foreign_revid(cls, foreign_revid):
514
        return { "git commit": foreign_revid }
515
516
0.200.1263 by Jelmer Vernooij
Fix foreign_vcs_git.
517
foreign_vcs_git = ForeignGit()
0.200.637 by Jelmer Vernooij
Allow single place for configuration of default mapping.
518
default_mapping = mapping_registry.get_default()()
0.200.212 by Jelmer Vernooij
Move conversion functions to mapping, use fetch_objects() from repository if present.
519
520
0.275.1 by Jelmer Vernooij
Use root_inventory.
521
def symlink_to_blob(symlink_target):
0.200.354 by Jelmer Vernooij
Support symlinks in conversion to git.
522
    from dulwich.objects import Blob
523
    blob = Blob()
0.200.795 by Jelmer Vernooij
simplify sha extraction for blobs, process multiple blobs at once.
524
    if type(symlink_target) == unicode:
525
        symlink_target = symlink_target.encode('utf-8')
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
526
    blob.data = symlink_target
0.200.354 by Jelmer Vernooij
Support symlinks in conversion to git.
527
    return blob
528
0.200.546 by Jelmer Vernooij
Add more docstrings, support storing unusual file modes.
529
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
530
def mode_is_executable(mode):
0.200.546 by Jelmer Vernooij
Add more docstrings, support storing unusual file modes.
531
    """Check if mode should be considered executable."""
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
532
    return bool(mode & 0111)
533
0.200.546 by Jelmer Vernooij
Add more docstrings, support storing unusual file modes.
534
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
535
def mode_kind(mode):
0.200.546 by Jelmer Vernooij
Add more docstrings, support storing unusual file modes.
536
    """Determine the Bazaar inventory kind based on Unix file mode."""
0.200.1538 by Jelmer Vernooij
More work on tree-reference support.
537
    if mode is None:
538
        return None
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
539
    entry_kind = (mode & 0700000) / 0100000
540
    if entry_kind == 0:
541
        return 'directory'
542
    elif entry_kind == 1:
543
        file_kind = (mode & 070000) / 010000
544
        if file_kind == 0:
545
            return 'file'
546
        elif file_kind == 2:
547
            return 'symlink'
548
        elif file_kind == 6:
549
            return 'tree-reference'
550
        else:
551
            raise AssertionError(
552
                "Unknown file kind %d, perms=%o." % (file_kind, mode,))
553
    else:
554
        raise AssertionError(
555
            "Unknown kind, perms=%r." % (mode,))
556
0.200.354 by Jelmer Vernooij
Support symlinks in conversion to git.
557
0.238.6 by Jelmer Vernooij
Support sending git am-style patches with "bzr send --format=git".
558
def object_mode(kind, executable):
559
    if kind == 'directory':
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
560
        return stat.S_IFDIR
0.238.6 by Jelmer Vernooij
Support sending git am-style patches with "bzr send --format=git".
561
    elif kind == 'symlink':
0.245.1 by INADA Naoki
Handle executable mode for symlink.
562
        mode = stat.S_IFLNK
563
        if executable:
0.200.703 by Jelmer Vernooij
Merge support for executable symlinks.
564
            mode |= 0111
0.245.1 by INADA Naoki
Handle executable mode for symlink.
565
        return mode
0.238.6 by Jelmer Vernooij
Support sending git am-style patches with "bzr send --format=git".
566
    elif kind == 'file':
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
567
        mode = stat.S_IFREG | 0644
0.238.6 by Jelmer Vernooij
Support sending git am-style patches with "bzr send --format=git".
568
        if executable:
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
569
            mode |= 0111
570
        return mode
0.200.665 by Jelmer Vernooij
Add more checks for submodules.
571
    elif kind == 'tree-reference':
572
        from dulwich.objects import S_IFGITLINK
573
        return S_IFGITLINK
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
574
    else:
575
        raise AssertionError
576
577
0.238.6 by Jelmer Vernooij
Support sending git am-style patches with "bzr send --format=git".
578
def entry_mode(entry):
579
    """Determine the git file mode for an inventory entry."""
580
    return object_mode(entry.kind, entry.executable)
581
582
0.275.4 by Jelmer Vernooij
Pass children list to directory_to_tree .
583
def directory_to_tree(children, lookup_ie_sha1, unusual_modes, empty_file_name,
584
                      allow_empty=False):
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
585
    """Create a Git Tree object from a Bazaar directory.
586
0.275.4 by Jelmer Vernooij
Pass children list to directory_to_tree .
587
    :param children: Children inventory entries
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
588
    :param lookup_ie_sha1: Lookup the Git SHA1 for a inventory entry
589
    :param unusual_modes: Dictionary with unusual file modes by file ids
590
    :param empty_file_name: Name to use for dummy files in empty directories,
591
        None to ignore empty directories.
592
    """
593
    from dulwich.objects import Blob, Tree
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
594
    tree = Tree()
0.275.4 by Jelmer Vernooij
Pass children list to directory_to_tree .
595
    for name, value in children.iteritems():
596
        ie = children[name]
0.200.549 by Jelmer Vernooij
Fix storing of unusual file modes.
597
        try:
598
            mode = unusual_modes[ie.file_id]
599
        except KeyError:
600
            mode = entry_mode(ie)
0.200.808 by Jelmer Vernooij
Avoid recalculating tree shas we already have.
601
        hexsha = lookup_ie_sha1(ie)
0.200.589 by Jelmer Vernooij
Fix handling of empty trees.
602
        if hexsha is not None:
0.200.1152 by Jelmer Vernooij
Require dulwich 0.7.1.
603
            tree.add(name.encode("utf-8"), mode, hexsha)
0.275.4 by Jelmer Vernooij
Pass children list to directory_to_tree .
604
    if not allow_empty and len(tree) == 0:
0.200.589 by Jelmer Vernooij
Fix handling of empty trees.
605
        # Only the root can be an empty tree
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
606
        if empty_file_name is not None:
0.200.1152 by Jelmer Vernooij
Require dulwich 0.7.1.
607
            tree.add(empty_file_name, stat.S_IFREG | 0644, Blob().id)
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
608
        else:
609
            return None
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
610
    return tree
611
612
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
613
def extract_unusual_modes(rev):
614
    try:
0.200.826 by Jelmer Vernooij
Fix some long lines.
615
        foreign_revid, mapping = mapping_registry.parse_revision_id(
616
            rev.revision_id)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
617
    except errors.InvalidRevisionId:
618
        return {}
619
    else:
620
        return mapping.export_unusual_file_modes(rev)
621
622
0.200.652 by Jelmer Vernooij
Split out git-svn-id parser as separate function, implement ForeignGit.serialize_foreign_revid.
623
def parse_git_svn_id(text):
624
    (head, uuid) = text.rsplit(" ", 1)
625
    (full_url, rev) = head.rsplit("@", 1)
0.200.653 by Jelmer Vernooij
Fix typo in git-svn-id parser, return revnum as integer.
626
    return (full_url, int(rev), uuid)
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
627
628
629
class GitFileIdMap(object):
630
631
    def __init__(self, file_ids, mapping):
632
        self.file_ids = file_ids
633
        self.paths = None
634
        self.mapping = mapping
635
0.200.1569 by Jelmer Vernooij
Implement GitRevisionTree.all_file_ids().
636
    def all_file_ids(self):
637
        return self.file_ids.values()
638
0.200.1201 by Jelmer Vernooij
Implement _set_root_id.
639
    def set_file_id(self, path, file_id):
0.200.1209 by Jelmer Vernooij
Check for types in file id map.
640
        assert type(path) is str
641
        assert type(file_id) is str
0.200.1201 by Jelmer Vernooij
Implement _set_root_id.
642
        self.file_ids[path] = file_id
643
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
644
    def lookup_file_id(self, path):
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
645
        assert type(path) is str
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
646
        try:
0.200.973 by Jelmer Vernooij
Add tests for generate_file_id.
647
            file_id = self.file_ids[path]
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
648
        except KeyError:
0.200.973 by Jelmer Vernooij
Add tests for generate_file_id.
649
            file_id = self.mapping.generate_file_id(path)
650
        assert type(file_id) is str
651
        return file_id
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
652
653
    def lookup_path(self, file_id):
654
        if self.paths is None:
655
            self.paths = {}
656
            for k, v in self.file_ids.iteritems():
657
                self.paths[v] = k
658
        try:
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
659
            path = self.paths[file_id]
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
660
        except KeyError:
661
            return self.mapping.parse_file_id(file_id)
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
662
        else:
663
            assert type(path) is str
664
            return path
0.200.1202 by Jelmer Vernooij
Implement has_or_had_id.
665
666
    def copy(self):
667
        return self.__class__(dict(self.file_ids), self.mapping)