/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
1
# Copyright (C) 2007 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""An adapter between a Git Repository and a Bazaar Branch"""
18
0.200.56 by Jelmer Vernooij
Switch to using GitPython rather than our own in-house stuff.
19
import git
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
20
import os
0.200.57 by Jelmer Vernooij
Fix more tests.
21
import time
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
22
23
import bzrlib
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
24
from bzrlib import (
0.200.20 by John Arbash Meinel
All tests are passing again
25
    deprecated_graph,
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
26
    errors,
0.200.38 by David Allouche
Reimplement GitRepository.get_inventory, simpler and faster.
27
    inventory,
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
28
    osutils,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
29
    repository,
0.200.29 by David Allouche
Smoke test for GitRepository.get_revision, and corresponding fixes.
30
    revision,
0.200.39 by David Allouche
Black-box text for "bzr log" in a git tree. Further simplification of GitRevisionTree.
31
    revisiontree,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
32
    urlutils,
0.200.60 by Jelmer Vernooij
Support signature functions.
33
    versionedfile,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
34
    )
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
35
from bzrlib.transport import get_transport
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
36
0.200.27 by David Allouche
Flat is better than nested, remove the gitlib hierarchy.
37
from bzrlib.plugins.git import (
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
38
    cache,
0.200.20 by John Arbash Meinel
All tests are passing again
39
    ids,
0.200.92 by Jelmer Vernooij
Update versionedfiles.
40
    versionedfiles
0.200.20 by John Arbash Meinel
All tests are passing again
41
    )
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
42
43
44
class GitRepository(repository.Repository):
45
    """An adapter to git repositories for bzr."""
46
0.200.41 by David Allouche
Define _serializer = None in GitRepository.
47
    _serializer = None
48
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
49
    def __init__(self, gitdir, lockfiles):
0.200.61 by Jelmer Vernooij
Fix tests.
50
        self.base = gitdir.root_transport.base
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
51
        self.bzrdir = gitdir
52
        self.control_files = lockfiles
0.200.90 by Jelmer Vernooij
Basic support for opening working trees.
53
        self._git = gitdir._git
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
54
        cache_dir = cache.create_cache_dir()
55
        cachedir_transport = get_transport(cache_dir)
56
        cache_file = os.path.join(cache_dir, 'cache-%s' % ids.NAMESPACE)
0.200.56 by Jelmer Vernooij
Switch to using GitPython rather than our own in-house stuff.
57
        self.texts = None
0.200.92 by Jelmer Vernooij
Update versionedfiles.
58
        self.signatures = versionedfiles.VirtualSignatureTexts(self)
59
        self.revisions = versionedfiles.VirtualRevisionTexts(self)
0.203.1 by Aaron Bentley
Make checkouts work
60
        self._format = GitFormat()
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
61
        self._fallback_repositories = []
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
62
0.200.74 by Jelmer Vernooij
Implement Repository.all_revision_ids().
63
    def _all_revision_ids(self):
64
        if self._git.heads == []:
65
            return set()
66
        ret = set()
67
        skip = 0
68
        max_count = 1000
69
        cms = None
70
        while cms != []:
71
            cms = self._git.commits("--all", max_count=max_count, skip=skip)
72
            skip += max_count
73
            ret.update([ids.convert_revision_id_git_to_bzr(cm.id) for cm in cms])
74
        return ret
75
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
76
    def is_shared(self):
77
        return True
78
0.200.40 by David Allouche
GitRepository.supports_rich_root() => False
79
    def supports_rich_root(self):
80
        return False
81
0.200.82 by Jelmer Vernooij
Support listing tags.
82
    #def get_revision_delta(self, revision_id):
83
    #    parent_revid = self.get_revision(revision_id).parent_ids[0]
84
    #    diff = self._git.diff(ids.convert_revision_id_bzr_to_git(parent_revid),
85
    #                   ids.convert_revision_id_bzr_to_git(revision_id))
86
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
87
    def get_ancestry(self, revision_id):
0.200.65 by Jelmer Vernooij
Implement get_ancestry properly.
88
        revision_id = revision.ensure_null(revision_id)
89
        ret = []
90
        if revision_id != revision.NULL_REVISION:
91
            skip = 0
92
            max_count = 1000
93
            cms = None
94
            while cms != []:
95
                cms = self._git.commits(ids.convert_revision_id_bzr_to_git(revision_id), max_count=max_count, skip=skip)
96
                skip += max_count
97
                ret += [ids.convert_revision_id_git_to_bzr(cm.id) for cm in cms]
98
        return [None] + ret
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
99
100
    def get_signature_text(self, revision_id):
101
        raise errors.NoSuchRevision(self, revision_id)
102
0.200.60 by Jelmer Vernooij
Support signature functions.
103
    def has_signature_for_revision_id(self, revision_id):
104
        return False
105
0.200.57 by Jelmer Vernooij
Fix more tests.
106
    def get_parent_map(self, revision_ids):
107
        ret = {}
108
        for revid in revision_ids:
0.200.77 by Jelmer Vernooij
Handle NULL_REVISION in get_parent_map.
109
            if revid == revision.NULL_REVISION:
110
                ret[revid] = ()
111
            else:
112
                commit = self._git.commit(ids.convert_revision_id_bzr_to_git(revid))
113
                ret[revid] = tuple([ids.convert_revision_id_git_to_bzr(p.id) for p in commit.parents])
0.200.57 by Jelmer Vernooij
Fix more tests.
114
        return ret
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
115
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
116
    def get_revision(self, revision_id):
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
117
        git_commit_id = ids.convert_revision_id_bzr_to_git(revision_id)
0.200.57 by Jelmer Vernooij
Fix more tests.
118
        commit = self._git.commit(git_commit_id)
0.204.5 by James Westby
Lose the debuggin prints.
119
        # print "fetched revision:", git_commit_id
0.200.57 by Jelmer Vernooij
Fix more tests.
120
        revision = self._parse_rev(commit)
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
121
        return revision
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
122
123
    def has_revision(self, revision_id):
124
        try:
125
            self.get_revision(revision_id)
126
        except NoSuchRevision:
127
            return False
128
        else:
129
            return True
130
131
    def get_revisions(self, revisions):
132
        return [self.get_revision(r) for r in revisions]
133
0.200.32 by David Allouche
Rewrite GitRepository._parse_rev, with unit tests.
134
    @classmethod
0.200.57 by Jelmer Vernooij
Fix more tests.
135
    def _parse_rev(klass, commit):
136
        """Convert a git commit to a bzr revision.
137
0.200.32 by David Allouche
Rewrite GitRepository._parse_rev, with unit tests.
138
        :return: a `bzrlib.revision.Revision` object.
139
        """
0.200.57 by Jelmer Vernooij
Fix more tests.
140
        rev = revision.Revision(ids.convert_revision_id_git_to_bzr(commit.id))
141
        rev.parent_ids = tuple([ids.convert_revision_id_git_to_bzr(p.id) for p in commit.parents])
0.200.32 by David Allouche
Rewrite GitRepository._parse_rev, with unit tests.
142
        rev.inventory_sha1 = ""
0.200.63 by Jelmer Vernooij
Ignore decoding errors since git doesn't support storing encoding.
143
        rev.message = commit.message.decode("utf-8", "replace")
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
144
        rev.committer = str(commit.committer)
145
        rev.properties['author'] = str(commit.author)
0.200.57 by Jelmer Vernooij
Fix more tests.
146
        rev.timestamp = time.mktime(commit.committed_date)
147
        rev.timezone = 0
0.200.32 by David Allouche
Rewrite GitRepository._parse_rev, with unit tests.
148
        return rev
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
149
150
    def revision_trees(self, revids):
151
        for revid in revids:
152
            yield self.revision_tree(revid)
153
154
    def revision_tree(self, revision_id):
0.200.57 by Jelmer Vernooij
Fix more tests.
155
        revision_id = revision.ensure_null(revision_id)
156
157
        if revision_id == revision.NULL_REVISION:
158
            inv = inventory.Inventory(root_id=None)
159
            inv.revision_id = revision_id
160
            return revisiontree.RevisionTree(self, inv, revision_id)
161
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
162
        return GitRevisionTree(self, revision_id)
163
164
    def get_inventory(self, revision_id):
0.200.57 by Jelmer Vernooij
Fix more tests.
165
        assert revision_id != None
166
        return self.revision_tree(revision_id).inventory
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
167
168
169
def escape_file_id(file_id):
170
    return file_id.replace('_', '__').replace(' ', '_s')
0.200.39 by David Allouche
Black-box text for "bzr log" in a git tree. Further simplification of GitRevisionTree.
171
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
172
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
173
def unescape_file_id(file_id):
174
    return file_id.replace("_s", " ").replace("__", "_")
175
176
0.200.39 by David Allouche
Black-box text for "bzr log" in a git tree. Further simplification of GitRevisionTree.
177
class GitRevisionTree(revisiontree.RevisionTree):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
178
179
    def __init__(self, repository, revision_id):
0.200.39 by David Allouche
Black-box text for "bzr log" in a git tree. Further simplification of GitRevisionTree.
180
        self._repository = repository
0.200.58 by Jelmer Vernooij
Fix remaining tests.
181
        self.revision_id = revision_id
0.200.57 by Jelmer Vernooij
Fix more tests.
182
        git_id = ids.convert_revision_id_bzr_to_git(revision_id)
183
        self.tree = repository._git.commit(git_id).tree
0.200.58 by Jelmer Vernooij
Fix remaining tests.
184
        self._inventory = inventory.Inventory(revision_id=revision_id)
185
        self._inventory.root.revision = revision_id
186
        self._build_inventory(self.tree, self._inventory.root, "")
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
187
0.200.79 by Jelmer Vernooij
Implement RevisionTree.get_revision_id().
188
    def get_revision_id(self):
189
        return self.revision_id
190
0.200.87 by Jelmer Vernooij
Remove cache usage.
191
    def get_file_text(self, file_id):
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
192
        entry = self._inventory[file_id]
0.200.87 by Jelmer Vernooij
Remove cache usage.
193
        if entry.kind == 'directory': return ""
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
194
        return self._repository._git.blob(entry.text_id).data
0.203.1 by Aaron Bentley
Make checkouts work
195
0.200.58 by Jelmer Vernooij
Fix remaining tests.
196
    def _build_inventory(self, tree, ie, path):
197
        assert isinstance(path, str)
198
        for b in tree.contents:
199
            basename = b.name.decode("utf-8")
200
            if path == "":
201
                child_path = b.name
202
            else:
203
                child_path = urlutils.join(path, b.name)
204
            file_id = escape_file_id(child_path.encode('utf-8'))
205
            if b.mode[0] == '0':
206
                child_ie = inventory.InventoryDirectory(file_id, basename, ie.file_id)
207
            elif b.mode[0] == '1':
208
                if b.mode[1] == '0':
209
                    child_ie = inventory.InventoryFile(file_id, basename, ie.file_id)
210
                    child_ie.text_sha1 = osutils.sha_string(b.data)
211
                elif b.mode[1] == '2':
212
                    child_ie = inventory.InventoryLink(file_id, basename, ie.file_id)
213
                    child_ie.text_sha1 = osutils.sha_string("")
214
                else:
215
                    raise AssertionError(
216
                        "Unknown file kind, perms=%r." % (b.mode,))
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
217
                child_ie.text_id = b.id
0.200.58 by Jelmer Vernooij
Fix remaining tests.
218
                child_ie.text_size = b.size
219
            else:
220
                raise AssertionError(
221
                    "Unknown blob kind, perms=%r." % (b.mode,))
222
            child_ie.executable = bool(int(b.mode[3:], 8) & 0111)
223
            child_ie.revision = self.revision_id
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
224
            self._inventory.add(child_ie)
0.200.58 by Jelmer Vernooij
Fix remaining tests.
225
            if b.mode[0] == '0':
226
                self._build_inventory(b, child_ie, child_path)
227
0.203.1 by Aaron Bentley
Make checkouts work
228
229
class GitFormat(object):
230
231
    supports_tree_reference = False
0.200.71 by Jelmer Vernooij
Implement GitRepositoryFormat.get_format_description.
232
233
    def get_format_description(self):
234
        return "Git Repository"