/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

  • Committer: Robert Collins
  • Date: 2007-03-25 08:59:56 UTC
  • mto: (2376.3.1 integration)
  • mto: This revision was merged to the branch mainline in revision 2401.
  • Revision ID: robertc@robertcollins.net-20070325085956-my8jv7cifqzyltyz
New SmartServer hooks facility. There are two initial hooks documented
in bzrlib.transport.smart.SmartServerHooks. The two initial hooks allow
plugins to execute code upon server startup and shutdown.
(Robert Collins).

SmartServer in standalone mode will now close its listening socket
when it stops, rather than waiting for garbage collection. This primarily
fixes test suite hangs when a test tries to connect to a shutdown server.
It may also help improve behaviour when dealing with a server running
on a specific port (rather than dynamically assigned ports).
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
2
 
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
#
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
 
18
 
"""An adapter between a Git Branch and a Bazaar Branch"""
19
 
 
20
 
from dulwich.objects import (
21
 
    Commit,
22
 
    Tag,
23
 
    )
24
 
 
25
 
from bzrlib import (
26
 
    branch,
27
 
    config,
28
 
    repository,
29
 
    revision,
30
 
    tag,
31
 
    transport,
32
 
    )
33
 
from bzrlib.decorators import (
34
 
    needs_read_lock,
35
 
    )
36
 
from bzrlib.trace import (
37
 
    mutter,
38
 
    )
39
 
 
40
 
from bzrlib.plugins.git.errors import (
41
 
    NoSuchRef,
42
 
    )
43
 
from bzrlib.plugins.git.foreign import (
44
 
    ForeignBranch,
45
 
    )
46
 
 
47
 
 
48
 
class LocalGitTagDict(tag.BasicTags):
49
 
    """Dictionary with tags in a local repository."""
50
 
 
51
 
    def __init__(self, branch):
52
 
        self.branch = branch
53
 
        self.repository = branch.repository
54
 
 
55
 
    def get_tag_dict(self):
56
 
        ret = {}
57
 
        for k,v in self.repository._git.tags.iteritems():
58
 
            obj = self.repository._git.get_object(v)
59
 
            while isinstance(obj, Tag):
60
 
                v = obj.object[1]
61
 
                obj = self.repository._git.get_object(v)
62
 
            if not isinstance(obj, Commit):
63
 
                mutter("Tag %s points at object %r that is not a commit, "
64
 
                       "ignoring", k, obj)
65
 
                continue
66
 
            ret[k] = self.branch.mapping.revision_id_foreign_to_bzr(v)
67
 
        return ret
68
 
 
69
 
    def set_tag(self, name, revid):
70
 
        self.repository._git.tags[name] = revid
71
 
 
72
 
 
73
 
class GitBranchConfig(config.BranchConfig):
74
 
    """BranchConfig that uses locations.conf in place of branch.conf"""
75
 
 
76
 
    def __init__(self, branch):
77
 
        config.BranchConfig.__init__(self, branch)
78
 
        # do not provide a BranchDataConfig
79
 
        self.option_sources = self.option_sources[0], self.option_sources[2]
80
 
 
81
 
    def set_user_option(self, name, value, store=config.STORE_BRANCH,
82
 
            warn_masked=False):
83
 
        """Force local to True"""
84
 
        config.BranchConfig.set_user_option(self, name, value,
85
 
            store=config.STORE_LOCATION, warn_masked=warn_masked)
86
 
 
87
 
 
88
 
class GitBranchFormat(branch.BranchFormat):
89
 
 
90
 
    def get_format_description(self):
91
 
        return 'Git Branch'
92
 
 
93
 
    def supports_tags(self):
94
 
        return True
95
 
 
96
 
    def make_tags(self, branch):
97
 
        if getattr(branch.repository, "get_refs", None) is not None:
98
 
            from bzrlib.plugins.git.remote import RemoteGitTagDict
99
 
            return RemoteGitTagDict(branch)
100
 
        else:
101
 
            return LocalGitTagDict(branch)
102
 
 
103
 
 
104
 
class GitBranch(ForeignBranch):
105
 
    """An adapter to git repositories for bzr Branch objects."""
106
 
 
107
 
    def __init__(self, bzrdir, repository, name, head, lockfiles):
108
 
        self.repository = repository
109
 
        self._format = GitBranchFormat()
110
 
        self.control_files = lockfiles
111
 
        self.bzrdir = bzrdir
112
 
        super(GitBranch, self).__init__(repository.get_mapping())
113
 
        self.name = name
114
 
        self.head = head
115
 
        self.base = bzrdir.transport.base
116
 
 
117
 
    def _get_nick(self, local=False, possible_master_transports=None):
118
 
        """Find the nick name for this branch.
119
 
 
120
 
        :return: Branch nick
121
 
        """
122
 
        return self.name
123
 
 
124
 
    nick = property(_get_nick)
125
 
 
126
 
    def dpull(self, source, stop_revision=None):
127
 
        if stop_revision is None:
128
 
            stop_revision = source.last_revision()
129
 
        # FIXME: Check for diverged branches
130
 
        revidmap = self.repository.dfetch(source.repository, stop_revision)
131
 
        self.head, self.mapping = self.mapping.revision_id_bzr_to_foreign(
132
 
            revidmap[stop_revision])
133
 
        self.repository._git.set_ref(self.name, self.head)
134
 
        return revidmap
135
 
 
136
 
    def lock_write(self):
137
 
        self.control_files.lock_write()
138
 
 
139
 
    def get_stacked_on_url(self):
140
 
        # Git doesn't do stacking (yet...)
141
 
        return None
142
 
 
143
 
    def get_parent(self):
144
 
        """See Branch.get_parent()."""
145
 
        # FIXME: Set "origin" url from .git/config ?
146
 
        return None
147
 
 
148
 
    def set_parent(self, url):
149
 
        # FIXME: Set "origin" url in .git/config ?
150
 
        pass
151
 
 
152
 
    def lock_read(self):
153
 
        self.control_files.lock_read()
154
 
 
155
 
    def unlock(self):
156
 
        self.control_files.unlock()
157
 
 
158
 
    def get_physical_lock_status(self):
159
 
        return False
160
 
 
161
 
 
162
 
class LocalGitBranch(GitBranch):
163
 
    """A local Git branch."""
164
 
 
165
 
    @needs_read_lock
166
 
    def last_revision(self):
167
 
        # perhaps should escape this ?
168
 
        if self.head is None:
169
 
            return revision.NULL_REVISION
170
 
        return self.mapping.revision_id_foreign_to_bzr(self.head)
171
 
 
172
 
    def _get_checkout_format(self):
173
 
        """Return the most suitable metadir for a checkout of this branch.
174
 
        Weaves are used if this branch's repository uses weaves.
175
 
        """
176
 
        format = self.repository.bzrdir.checkout_metadir()
177
 
        format.set_branch_format(self._format)
178
 
        return format
179
 
 
180
 
    def create_checkout(self, to_location, revision_id=None, lightweight=False,
181
 
        accelerator_tree=None, hardlink=False):
182
 
        if lightweight:
183
 
            t = transport.get_transport(to_location)
184
 
            t.ensure_base()
185
 
            format = self._get_checkout_format()
186
 
            checkout = format.initialize_on_transport(t)
187
 
            from_branch = branch.BranchReferenceFormat().initialize(checkout, 
188
 
                self)
189
 
            tree = checkout.create_workingtree(revision_id,
190
 
                from_branch=from_branch, hardlink=hardlink)
191
 
            return tree
192
 
        else:
193
 
            return self._create_heavyweight_checkout(to_location, revision_id,
194
 
            hardlink)
195
 
 
196
 
    def _create_heavyweight_checkout(self, to_location, revision_id=None, 
197
 
                                     hardlink=False):
198
 
        """Create a new heavyweight checkout of this branch.
199
 
 
200
 
        :param to_location: URL of location to create the new checkout in.
201
 
        :param revision_id: Revision that should be the tip of the checkout.
202
 
        :param hardlink: Whether to hardlink
203
 
        :return: WorkingTree object of checkout.
204
 
        """
205
 
        checkout_branch = BzrDir.create_branch_convenience(
206
 
            to_location, force_new_tree=False, format=get_rich_root_format())
207
 
        checkout = checkout_branch.bzrdir
208
 
        checkout_branch.bind(self)
209
 
        # pull up to the specified revision_id to set the initial 
210
 
        # branch tip correctly, and seed it with history.
211
 
        checkout_branch.pull(self, stop_revision=revision_id)
212
 
        return checkout.create_workingtree(revision_id, hardlink=hardlink)
213
 
 
214
 
    def _gen_revision_history(self):
215
 
        if self.head is None:
216
 
            return []
217
 
        ret = list(self.repository.iter_reverse_revision_history(
218
 
            self.last_revision()))
219
 
        ret.reverse()
220
 
        return ret
221
 
 
222
 
    def get_config(self):
223
 
        return GitBranchConfig(self)
224
 
 
225
 
    def get_push_location(self):
226
 
        """See Branch.get_push_location."""
227
 
        push_loc = self.get_config().get_user_option('push_location')
228
 
        return push_loc
229
 
 
230
 
    def set_push_location(self, location):
231
 
        """See Branch.set_push_location."""
232
 
        self.get_config().set_user_option('push_location', location,
233
 
                                          store=config.STORE_LOCATION)
234
 
 
235
 
    def supports_tags(self):
236
 
        return True
237
 
 
238
 
 
239
 
class InterGitGenericBranch(branch.InterBranch):
240
 
    """InterBranch implementation that pulls from Git into bzr."""
241
 
 
242
 
    @classmethod
243
 
    def is_compatible(self, source, target):
244
 
        return isinstance(source, GitBranch)
245
 
 
246
 
    def update_revisions(self, stop_revision=None, overwrite=False,
247
 
        graph=None):
248
 
        """See InterBranch.update_revisions()."""
249
 
        interrepo = repository.InterRepository.get(self.source.repository, 
250
 
            self.target.repository)
251
 
        self._last_revid = None
252
 
        def determine_wants(heads):
253
 
            if not self.source.name in heads:
254
 
                raise NoSuchRef(self.source.name, heads.keys())
255
 
            if stop_revision is not None:
256
 
                self._last_revid = stop_revision
257
 
                head, mapping = self.source.repository.lookup_git_revid(
258
 
                    stop_revision)
259
 
            else:
260
 
                head = heads[self.source.name]
261
 
                self._last_revid = \
262
 
                    self.source.mapping.revision_id_foreign_to_bzr(head)
263
 
            if self.target.repository.has_revision(self._last_revid):
264
 
                return []
265
 
            return [head]
266
 
        interrepo.fetch_objects(determine_wants, self.source.mapping)
267
 
        if overwrite:
268
 
            prev_last_revid = None
269
 
        else:
270
 
            prev_last_revid = self.target.last_revision()
271
 
        self.target.generate_revision_history(self._last_revid, prev_last_revid)
272
 
 
273
 
 
274
 
branch.InterBranch.register_optimiser(InterGitGenericBranch)