/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
1
# Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
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
"""A Git repository implementation that uses a Bazaar transport."""
18
19
20
from dulwich.errors import (
21
    NotGitRepository,
0.246.7 by Jelmer Vernooij
more work.
22
    NoIndexPresent,
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
23
    )
0.246.4 by Jelmer Vernooij
more work on transportgit.
24
from dulwich.objects import (
25
    ShaFile,
26
    )
27
from dulwich.object_store import (
28
    PackBasedObjectStore,
29
    PACKDIR,
30
    )
31
from dulwich.pack import (
0.246.7 by Jelmer Vernooij
more work.
32
    PackData,
0.246.4 by Jelmer Vernooij
more work on transportgit.
33
    Pack,
0.246.7 by Jelmer Vernooij
more work.
34
    load_pack_index_file,
0.246.4 by Jelmer Vernooij
more work on transportgit.
35
    )
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
36
from dulwich.repo import (
37
    BaseRepo,
0.246.8 by Jelmer Vernooij
simplify refs handling.
38
    DictRefsContainer,
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
39
    OBJECTDIR,
0.246.8 by Jelmer Vernooij
simplify refs handling.
40
    read_info_refs,
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
41
    )
42
43
from bzrlib.errors import (
44
    NoSuchFile,
45
    )
46
47
48
class TransportRepo(BaseRepo):
49
50
    def __init__(self, transport):
51
        self.transport = transport
0.246.8 by Jelmer Vernooij
simplify refs handling.
52
        if self.transport.has(".git/info/refs"):
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
53
            self.bare = False
54
            self._controltransport = self.transport.clone('.git')
0.246.8 by Jelmer Vernooij
simplify refs handling.
55
        elif self.transport.has("info/refs"):
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
56
            self.bare = True
57
            self._controltransport = self.transport
58
        else:
59
            raise NotGitRepository(self.transport)
60
        object_store = TransportObjectStore(
61
            self._controltransport.clone(OBJECTDIR))
0.246.8 by Jelmer Vernooij
simplify refs handling.
62
        refs = {}
63
        refs["HEAD"] = self._controltransport.get_bytes("HEAD").rstrip("\n")
64
        refs.update(read_info_refs(self._controltransport.get('info/refs')))
65
        super(TransportRepo, self).__init__(object_store, 
66
                DictRefsContainer(refs))
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
67
68
    def get_named_file(self, path):
69
        """Get a file from the control dir with a specific name.
70
71
        Although the filename should be interpreted as a filename relative to
72
        the control dir in a disk-baked Repo, the object returned need not be
73
        pointing to a file in that location.
74
75
        :param path: The path to the file, relative to the control dir.
76
        :return: An open file object, or None if the file does not exist.
77
        """
78
        try:
79
            return self._controltransport.get(path.lstrip('/'))
80
        except NoSuchFile:
81
            return None
82
83
    def open_index(self):
84
        """Open the index for this repository."""
0.246.9 by Jelmer Vernooij
Remove unused write code.
85
        raise NoIndexPresent()
0.246.1 by Jelmer Vernooij
Add TransportRepo class.
86
87
    def __repr__(self):
88
        return "<TransportRepo for %r>" % self.transport
89
0.246.4 by Jelmer Vernooij
more work on transportgit.
90
91
class TransportObjectStore(PackBasedObjectStore):
92
    """Git-style object store that exists on disk."""
93
94
    def __init__(self, transport):
95
        """Open an object store.
96
97
        :param transport: Transport to open data from
98
        """
99
        super(TransportObjectStore, self).__init__()
100
        self.transport = transport
101
        self.pack_transport = self.transport.clone(PACKDIR)
102
103
    def _load_packs(self):
0.246.7 by Jelmer Vernooij
more work.
104
        ret = []
0.246.9 by Jelmer Vernooij
Remove unused write code.
105
        for line in self.transport.get('info/packs').readlines():
0.246.11 by Jelmer Vernooij
Cope with empty lines in packs info file.
106
            line = line.rstrip("\n")
107
            if not line:
108
                continue
109
            (kind, name) = line.split(" ", 1)
0.246.9 by Jelmer Vernooij
Remove unused write code.
110
            if kind != "P":
111
                continue
112
            if name.startswith("pack-") and name.endswith(".pack"):
113
                pd = PackData.from_file(self.pack_transport.get(name))
114
                idxname = name.replace(".pack", ".idx")
115
                idx = load_pack_index_file(idxname, self.pack_transport.get(idxname))
116
                ret.append(Pack.from_objects(pd, idx))
0.246.7 by Jelmer Vernooij
more work.
117
        return ret
0.246.4 by Jelmer Vernooij
more work on transportgit.
118
119
    def _iter_loose_objects(self):
120
        for base in self.transport.list_dir('.'):
121
            if len(base) != 2:
122
                continue
123
            for rest in self.transport.list_dir(base):
124
                yield base+rest
125
126
    def _split_loose_object(self, sha):
127
        return (sha[:2], sha[2:])
128
129
    def _get_loose_object(self, sha):
130
        path = '%s/%s' % self._split_loose_object(sha)
131
        try:
0.246.7 by Jelmer Vernooij
more work.
132
            return ShaFile._parse_file(self.transport.get(path).read())
0.246.4 by Jelmer Vernooij
more work on transportgit.
133
        except NoSuchFile:
134
            return None
135
136
    def add_object(self, obj):
137
        """Add a single object to this object store.
138
139
        :param obj: Object to add
140
        """
141
        (dir, file) = self._split_loose_object(obj.id)
142
        self.transport.mkdir(dir)
143
        path = "%s/%s" % (dir, file)
144
        if self.transport.has(path):
145
            return # Already there, no need to write again
146
        self.transport.put_bytes(path, obj.as_legacy_object())
147
148
    def add_pack(self):
149
        """Add a new pack to this object store. 
150
151
        :return: Fileobject to write to and a commit function to 
152
            call when the pack is finished.
153
        """
0.246.9 by Jelmer Vernooij
Remove unused write code.
154
        raise NotImplementedError(self.add_pack)