/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to branch.py

Minor improvements to log performance by calling outf.write once (only) per revision and tuning date formatting speed

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 Branch and a Bazaar Branch"""
18
 
 
19
 
from bzrlib import (
20
 
    branch,
21
 
    config,
22
 
    repository,
23
 
    revision,
24
 
    tag,
25
 
    )
26
 
from bzrlib.decorators import needs_read_lock
27
 
from bzrlib.trace import mutter
28
 
 
29
 
from bzrlib.plugins.git.foreign import ForeignBranch
30
 
from bzrlib.plugins.git.errors import LightWeightCheckoutsNotSupported
31
 
 
32
 
from dulwich.objects import (
33
 
        Commit,
34
 
        Tag,
35
 
        )
36
 
 
37
 
class GitTagDict(tag.BasicTags):
38
 
 
39
 
    def __init__(self, branch):
40
 
        self.branch = branch
41
 
        self.repository = branch.repository
42
 
 
43
 
    def get_tag_dict(self):
44
 
        ret = {}
45
 
        for k,v in self.repository._git.tags.iteritems():
46
 
            obj = self.repository._git.get_object(v)
47
 
            while isinstance(obj, Tag):
48
 
                v = obj.object[1]
49
 
                obj = self.repository._git.get_object(v)
50
 
            if not isinstance(obj, Commit):
51
 
                mutter("Tag %s points at object %r that is not a commit, ignoring", k, obj)
52
 
                continue
53
 
            ret[k] = self.branch.mapping.revision_id_foreign_to_bzr(v)
54
 
        return ret
55
 
 
56
 
    def set_tag(self, name, revid):
57
 
        self.repository._git.tags[name] = revid
58
 
 
59
 
 
60
 
class GitBranchConfig(config.BranchConfig):
61
 
    """BranchConfig that uses locations.conf in place of branch.conf"""
62
 
 
63
 
    def __init__(self, branch):
64
 
        config.BranchConfig.__init__(self, branch)
65
 
        # do not provide a BranchDataConfig
66
 
        self.option_sources = self.option_sources[0], self.option_sources[2]
67
 
 
68
 
    def set_user_option(self, name, value, store=config.STORE_BRANCH, warn_masked=False):
69
 
        """Force local to True"""
70
 
        config.BranchConfig.set_user_option(self, name, value, store=config.STORE_LOCATION, warn_masked=warn_masked)
71
 
 
72
 
 
73
 
class GitBranchFormat(branch.BranchFormat):
74
 
 
75
 
    def get_format_description(self):
76
 
        return 'Git Branch'
77
 
 
78
 
    def supports_tags(self):
79
 
        return True
80
 
 
81
 
 
82
 
class GitBranch(ForeignBranch):
83
 
    """An adapter to git repositories for bzr Branch objects."""
84
 
 
85
 
    def __init__(self, bzrdir, repository, name, head, lockfiles):
86
 
        self.repository = repository
87
 
        super(GitBranch, self).__init__(repository.get_mapping())
88
 
        self.control_files = lockfiles
89
 
        self.bzrdir = bzrdir
90
 
        self.name = name
91
 
        self.head = head
92
 
        self.base = bzrdir.transport.base
93
 
        self._format = GitBranchFormat()
94
 
 
95
 
    def dpull(self, source, stop_revision=None):
96
 
        if stop_revision is None:
97
 
            stop_revision = source.last_revision()
98
 
        # FIXME: Check for diverged branches
99
 
        revidmap = self.repository.dfetch(source.repository, stop_revision)
100
 
        self.head, self.mapping = self.mapping.revision_id_bzr_to_foreign(revidmap[stop_revision])
101
 
        return revidmap
102
 
 
103
 
    def lock_write(self):
104
 
        self.control_files.lock_write()
105
 
 
106
 
    def get_stacked_on_url(self):
107
 
        # Git doesn't do stacking (yet...)
108
 
        return None
109
 
 
110
 
    def get_parent(self):
111
 
        """See Branch.get_parent()."""
112
 
        return None
113
 
 
114
 
    def set_parent(self, url):
115
 
        pass
116
 
 
117
 
    def lock_read(self):
118
 
        self.control_files.lock_read()
119
 
 
120
 
    def unlock(self):
121
 
        self.control_files.unlock()
122
 
 
123
 
    def get_physical_lock_status(self):
124
 
        return False
125
 
 
126
 
 
127
 
class LocalGitBranch(GitBranch):
128
 
 
129
 
    @needs_read_lock
130
 
    def last_revision(self):
131
 
        # perhaps should escape this ?
132
 
        if self.head is None:
133
 
            return revision.NULL_REVISION
134
 
        return self.mapping.revision_id_foreign_to_bzr(self.head)
135
 
 
136
 
    def create_checkout(self, to_location, revision_id=None, 
137
 
                        lightweight=False, accelerator_tree=None, hardlink=False):
138
 
        if lightweight:
139
 
            raise LightWeightCheckoutsNotSupported()
140
 
        return self._create_heavyweight_checkout(to_location, revision_id, hardlink)
141
 
 
142
 
    def _create_heavyweight_checkout(self, to_location, revision_id=None, 
143
 
                                     hardlink=False):
144
 
        """Create a new heavyweight checkout of this branch.
145
 
 
146
 
        :param to_location: URL of location to create the new checkout in.
147
 
        :param revision_id: Revision that should be the tip of the checkout.
148
 
        :param hardlink: Whether to hardlink
149
 
        :return: WorkingTree object of checkout.
150
 
        """
151
 
        checkout_branch = BzrDir.create_branch_convenience(
152
 
            to_location, force_new_tree=False, format=get_rich_root_format())
153
 
        checkout = checkout_branch.bzrdir
154
 
        checkout_branch.bind(self)
155
 
        # pull up to the specified revision_id to set the initial 
156
 
        # branch tip correctly, and seed it with history.
157
 
        checkout_branch.pull(self, stop_revision=revision_id)
158
 
        return checkout.create_workingtree(revision_id, hardlink=hardlink)
159
 
 
160
 
    def _make_tags(self):
161
 
        return GitTagDict(self)
162
 
 
163
 
    def _gen_revision_history(self):
164
 
        if self.head is None:
165
 
            return []
166
 
        ret = list(self.repository.iter_reverse_revision_history(self.last_revision()))
167
 
        ret.reverse()
168
 
        return ret
169
 
 
170
 
    def get_config(self):
171
 
        return GitBranchConfig(self)
172
 
 
173
 
    def get_push_location(self):
174
 
        """See Branch.get_push_location."""
175
 
        push_loc = self.get_config().get_user_option('push_location')
176
 
        return push_loc
177
 
 
178
 
    def set_push_location(self, location):
179
 
        """See Branch.set_push_location."""
180
 
        self.get_config().set_user_option('push_location', location,
181
 
                                          store=config.STORE_LOCATION)
182
 
 
183
 
    def supports_tags(self):
184
 
        return True
185
 
 
186
 
    def sprout(self, to_bzrdir, revision_id=None):
187
 
        """See Branch.sprout()."""
188
 
        result = to_bzrdir.create_branch()
189
 
        self.copy_content_into(result, revision_id=revision_id)
190
 
        result.set_parent(self.bzrdir.root_transport.base)
191
 
        return result
192
 
 
193
 
 
194
 
class InterGitGenericBranch(branch.InterBranch):
195
 
 
196
 
    @classmethod
197
 
    def is_compatible(self, source, target):
198
 
        return isinstance(source, GitBranch)
199
 
 
200
 
    def update_revisions(self, stop_revision=None, overwrite=False,
201
 
        graph=None):
202
 
        """See InterBranch.update_revisions()."""
203
 
        # TODO: stop_revision, overwrite
204
 
        interrepo = repository.InterRepository.get(self.source.repository, self.target.repository)
205
 
        self._last_revid = None
206
 
        def determine_wants(heads):
207
 
            if not self.source.name in heads:
208
 
                raise BzrError("No such remote branch '%s', found: %r" % (
209
 
                    self.source.name, heads.keys()))
210
 
            head = heads[self.source.name]
211
 
            self._last_revid = self.source.mapping.revision_id_foreign_to_bzr(head)
212
 
            if self.target.repository.has_revision(self._last_revid):
213
 
                return []
214
 
            return [head]
215
 
        interrepo.fetch_objects(determine_wants, self.source.mapping)
216
 
        self.target.generate_revision_history(self._last_revid)
217
 
 
218
 
 
219
 
branch.InterBranch.register_optimiser(InterGitGenericBranch)