/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,
40
    )
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
41
42
43
class GitRepository(repository.Repository):
44
    """An adapter to git repositories for bzr."""
45
0.200.41 by David Allouche
Define _serializer = None in GitRepository.
46
    _serializer = None
47
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
48
    def __init__(self, gitdir, lockfiles):
0.200.61 by Jelmer Vernooij
Fix tests.
49
        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.
50
        self.bzrdir = gitdir
51
        self.control_files = lockfiles
0.200.56 by Jelmer Vernooij
Switch to using GitPython rather than our own in-house stuff.
52
        self._git = git.repo.Repo(gitdir.root_transport.local_abspath("."))
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
53
        cache_dir = cache.create_cache_dir()
54
        cachedir_transport = get_transport(cache_dir)
55
        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.
56
        self.texts = None
0.200.60 by Jelmer Vernooij
Support signature functions.
57
        self.signatures = versionedfile.VirtualSignatureTexts(self)
0.200.74 by Jelmer Vernooij
Implement Repository.all_revision_ids().
58
        self.revisions = versionedfile.VirtualRevisionTexts(self)
0.203.1 by Aaron Bentley
Make checkouts work
59
        self._format = GitFormat()
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
60
        self._fallback_repositories = []
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
61
0.200.74 by Jelmer Vernooij
Implement Repository.all_revision_ids().
62
    def _all_revision_ids(self):
63
        if self._git.heads == []:
64
            return set()
65
        ret = set()
66
        skip = 0
67
        max_count = 1000
68
        cms = None
69
        while cms != []:
70
            cms = self._git.commits("--all", max_count=max_count, skip=skip)
71
            skip += max_count
72
            ret.update([ids.convert_revision_id_git_to_bzr(cm.id) for cm in cms])
73
        return ret
74
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
75
    def is_shared(self):
76
        return True
77
0.200.40 by David Allouche
GitRepository.supports_rich_root() => False
78
    def supports_rich_root(self):
79
        return False
80
0.200.82 by Jelmer Vernooij
Support listing tags.
81
    #def get_revision_delta(self, revision_id):
82
    #    parent_revid = self.get_revision(revision_id).parent_ids[0]
83
    #    diff = self._git.diff(ids.convert_revision_id_bzr_to_git(parent_revid),
84
    #                   ids.convert_revision_id_bzr_to_git(revision_id))
85
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
86
    def get_ancestry(self, revision_id):
0.200.65 by Jelmer Vernooij
Implement get_ancestry properly.
87
        revision_id = revision.ensure_null(revision_id)
88
        ret = []
89
        if revision_id != revision.NULL_REVISION:
90
            skip = 0
91
            max_count = 1000
92
            cms = None
93
            while cms != []:
94
                cms = self._git.commits(ids.convert_revision_id_bzr_to_git(revision_id), max_count=max_count, skip=skip)
95
                skip += max_count
96
                ret += [ids.convert_revision_id_git_to_bzr(cm.id) for cm in cms]
97
        return [None] + ret
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
98
99
    def get_signature_text(self, revision_id):
100
        raise errors.NoSuchRevision(self, revision_id)
101
0.200.60 by Jelmer Vernooij
Support signature functions.
102
    def has_signature_for_revision_id(self, revision_id):
103
        return False
104
0.200.57 by Jelmer Vernooij
Fix more tests.
105
    def get_parent_map(self, revision_ids):
106
        ret = {}
107
        for revid in revision_ids:
0.200.77 by Jelmer Vernooij
Handle NULL_REVISION in get_parent_map.
108
            if revid == revision.NULL_REVISION:
109
                ret[revid] = ()
110
            else:
111
                commit = self._git.commit(ids.convert_revision_id_bzr_to_git(revid))
112
                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.
113
        return ret
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
114
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
115
    def get_revision(self, revision_id):
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
116
        git_commit_id = ids.convert_revision_id_bzr_to_git(revision_id)
0.200.57 by Jelmer Vernooij
Fix more tests.
117
        commit = self._git.commit(git_commit_id)
0.204.5 by James Westby
Lose the debuggin prints.
118
        # print "fetched revision:", git_commit_id
0.200.57 by Jelmer Vernooij
Fix more tests.
119
        revision = self._parse_rev(commit)
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
120
        return revision
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
121
122
    def has_revision(self, revision_id):
123
        try:
124
            self.get_revision(revision_id)
125
        except NoSuchRevision:
126
            return False
127
        else:
128
            return True
129
130
    def get_revisions(self, revisions):
131
        return [self.get_revision(r) for r in revisions]
132
0.200.32 by David Allouche
Rewrite GitRepository._parse_rev, with unit tests.
133
    @classmethod
0.200.57 by Jelmer Vernooij
Fix more tests.
134
    def _parse_rev(klass, commit):
135
        """Convert a git commit to a bzr revision.
136
0.200.32 by David Allouche
Rewrite GitRepository._parse_rev, with unit tests.
137
        :return: a `bzrlib.revision.Revision` object.
138
        """
0.200.57 by Jelmer Vernooij
Fix more tests.
139
        rev = revision.Revision(ids.convert_revision_id_git_to_bzr(commit.id))
140
        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.
141
        rev.inventory_sha1 = ""
0.200.63 by Jelmer Vernooij
Ignore decoding errors since git doesn't support storing encoding.
142
        rev.message = commit.message.decode("utf-8", "replace")
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
143
        rev.committer = str(commit.committer)
144
        rev.properties['author'] = str(commit.author)
0.200.57 by Jelmer Vernooij
Fix more tests.
145
        rev.timestamp = time.mktime(commit.committed_date)
146
        rev.timezone = 0
0.200.32 by David Allouche
Rewrite GitRepository._parse_rev, with unit tests.
147
        return rev
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
148
149
    def revision_trees(self, revids):
150
        for revid in revids:
151
            yield self.revision_tree(revid)
152
153
    def revision_tree(self, revision_id):
0.200.57 by Jelmer Vernooij
Fix more tests.
154
        revision_id = revision.ensure_null(revision_id)
155
156
        if revision_id == revision.NULL_REVISION:
157
            inv = inventory.Inventory(root_id=None)
158
            inv.revision_id = revision_id
159
            return revisiontree.RevisionTree(self, inv, revision_id)
160
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
161
        return GitRevisionTree(self, revision_id)
162
163
    def get_inventory(self, revision_id):
0.200.57 by Jelmer Vernooij
Fix more tests.
164
        assert revision_id != None
165
        return self.revision_tree(revision_id).inventory
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
166
167
168
def escape_file_id(file_id):
169
    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.
170
0.200.45 by David Allouche
More performance hacking, introduce sqlite cache, escape characters in commits that break serializers.
171
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
172
def unescape_file_id(file_id):
173
    return file_id.replace("_s", " ").replace("__", "_")
174
175
0.200.39 by David Allouche
Black-box text for "bzr log" in a git tree. Further simplification of GitRevisionTree.
176
class GitRevisionTree(revisiontree.RevisionTree):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
177
178
    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.
179
        self._repository = repository
0.200.58 by Jelmer Vernooij
Fix remaining tests.
180
        self.revision_id = revision_id
0.200.57 by Jelmer Vernooij
Fix more tests.
181
        git_id = ids.convert_revision_id_bzr_to_git(revision_id)
182
        self.tree = repository._git.commit(git_id).tree
0.200.58 by Jelmer Vernooij
Fix remaining tests.
183
        self._inventory = inventory.Inventory(revision_id=revision_id)
184
        self._inventory.root.revision = revision_id
185
        self._build_inventory(self.tree, self._inventory.root, "")
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
186
0.200.79 by Jelmer Vernooij
Implement RevisionTree.get_revision_id().
187
    def get_revision_id(self):
188
        return self.revision_id
189
0.200.87 by Jelmer Vernooij
Remove cache usage.
190
    def get_file_text(self, file_id):
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
191
        entry = self._inventory[file_id]
0.200.87 by Jelmer Vernooij
Remove cache usage.
192
        if entry.kind == 'directory': return ""
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
193
        return self._repository._git.blob(entry.text_id).data
0.203.1 by Aaron Bentley
Make checkouts work
194
0.200.58 by Jelmer Vernooij
Fix remaining tests.
195
    def _build_inventory(self, tree, ie, path):
196
        assert isinstance(path, str)
197
        for b in tree.contents:
198
            basename = b.name.decode("utf-8")
199
            if path == "":
200
                child_path = b.name
201
            else:
202
                child_path = urlutils.join(path, b.name)
203
            file_id = escape_file_id(child_path.encode('utf-8'))
204
            if b.mode[0] == '0':
205
                child_ie = inventory.InventoryDirectory(file_id, basename, ie.file_id)
206
            elif b.mode[0] == '1':
207
                if b.mode[1] == '0':
208
                    child_ie = inventory.InventoryFile(file_id, basename, ie.file_id)
209
                    child_ie.text_sha1 = osutils.sha_string(b.data)
210
                elif b.mode[1] == '2':
211
                    child_ie = inventory.InventoryLink(file_id, basename, ie.file_id)
212
                    child_ie.text_sha1 = osutils.sha_string("")
213
                else:
214
                    raise AssertionError(
215
                        "Unknown file kind, perms=%r." % (b.mode,))
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
216
                child_ie.text_id = b.id
0.200.58 by Jelmer Vernooij
Fix remaining tests.
217
                child_ie.text_size = b.size
218
            else:
219
                raise AssertionError(
220
                    "Unknown blob kind, perms=%r." % (b.mode,))
221
            child_ie.executable = bool(int(b.mode[3:], 8) & 0111)
222
            child_ie.revision = self.revision_id
0.200.88 by Jelmer Vernooij
Fix RevisionTree.get_file_text().
223
            self._inventory.add(child_ie)
0.200.58 by Jelmer Vernooij
Fix remaining tests.
224
            if b.mode[0] == '0':
225
                self._build_inventory(b, child_ie, child_path)
226
0.203.1 by Aaron Bentley
Make checkouts work
227
228
class GitFormat(object):
229
230
    supports_tree_reference = False
0.200.71 by Jelmer Vernooij
Implement GitRepositoryFormat.get_format_description.
231
232
    def get_format_description(self):
233
        return "Git Repository"