/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
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
2
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
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
0.200.261 by Jelmer Vernooij
More formatting fixes.
20
from dulwich.objects import (
21
    Commit,
22
    Tag,
23
    )
24
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
25
from bzrlib import (
26
    branch,
27
    config,
0.200.327 by Jelmer Vernooij
merge new bzr-foreign.
28
    foreign,
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
29
    repository,
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
30
    revision,
0.200.82 by Jelmer Vernooij
Support listing tags.
31
    tag,
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
32
    transport,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
33
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
34
from bzrlib.decorators import (
35
    needs_read_lock,
36
    )
37
from bzrlib.trace import (
0.200.342 by Jelmer Vernooij
Report git sha during pull.
38
    is_quiet,
0.200.261 by Jelmer Vernooij
More formatting fixes.
39
    mutter,
40
    )
41
0.200.386 by Jelmer Vernooij
Move config to a separate file, support BranchConfig.username().
42
from bzrlib.plugins.git.config import (
43
    GitBranchConfig,
44
    )
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
45
from bzrlib.plugins.git.errors import (
46
    NoSuchRef,
47
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
48
49
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
50
class GitPullResult(branch.PullResult):
51
52
    def _lookup_revno(self, revid):
53
        assert isinstance(revid, str), "was %r" % revid
54
        # Try in source branch first, it'll be faster
55
        return self.target_branch.revision_id_to_revno(revid)
56
57
    @property
58
    def old_revno(self):
59
        return self._lookup_revno(self.old_revid)
60
61
    @property
62
    def new_revno(self):
63
        return self._lookup_revno(self.new_revid)
64
65
0.200.261 by Jelmer Vernooij
More formatting fixes.
66
class LocalGitTagDict(tag.BasicTags):
67
    """Dictionary with tags in a local repository."""
0.200.82 by Jelmer Vernooij
Support listing tags.
68
0.200.89 by Jelmer Vernooij
Support sprouting branches.
69
    def __init__(self, branch):
70
        self.branch = branch
71
        self.repository = branch.repository
0.200.82 by Jelmer Vernooij
Support listing tags.
72
73
    def get_tag_dict(self):
74
        ret = {}
0.200.180 by Jelmer Vernooij
Simplify tag handling.
75
        for k,v in self.repository._git.tags.iteritems():
0.200.194 by Jelmer Vernooij
Look for commit object in heavyweight tags.
76
            obj = self.repository._git.get_object(v)
77
            while isinstance(obj, Tag):
78
                v = obj.object[1]
79
                obj = self.repository._git.get_object(v)
80
            if not isinstance(obj, Commit):
0.200.261 by Jelmer Vernooij
More formatting fixes.
81
                mutter("Tag %s points at object %r that is not a commit, "
82
                       "ignoring", k, obj)
0.200.194 by Jelmer Vernooij
Look for commit object in heavyweight tags.
83
                continue
0.200.180 by Jelmer Vernooij
Simplify tag handling.
84
            ret[k] = self.branch.mapping.revision_id_foreign_to_bzr(v)
0.200.82 by Jelmer Vernooij
Support listing tags.
85
        return ret
86
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
87
    def set_tag(self, name, revid):
0.200.181 by Jelmer Vernooij
Support setting tags.
88
        self.repository._git.tags[name] = revid
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
89
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
90
91
class GitBranchFormat(branch.BranchFormat):
92
0.200.70 by Jelmer Vernooij
Implement GitBranchFormat.get_format_description.
93
    def get_format_description(self):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
94
        return 'Git Branch'
95
0.200.82 by Jelmer Vernooij
Support listing tags.
96
    def supports_tags(self):
97
        return True
98
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
99
    def make_tags(self, branch):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
100
        if getattr(branch.repository, "get_refs", None) is not None:
101
            from bzrlib.plugins.git.remote import RemoteGitTagDict
102
            return RemoteGitTagDict(branch)
0.200.261 by Jelmer Vernooij
More formatting fixes.
103
        else:
104
            return LocalGitTagDict(branch)
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
105
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
106
0.200.327 by Jelmer Vernooij
merge new bzr-foreign.
107
class GitBranch(foreign.ForeignBranch):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
108
    """An adapter to git repositories for bzr Branch objects."""
109
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
110
    def __init__(self, bzrdir, repository, name, head, lockfiles):
0.200.82 by Jelmer Vernooij
Support listing tags.
111
        self.repository = repository
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
112
        self._format = GitBranchFormat()
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
113
        self.control_files = lockfiles
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
114
        self.bzrdir = bzrdir
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
115
        super(GitBranch, self).__init__(repository.get_mapping())
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
116
        self.name = name
0.200.57 by Jelmer Vernooij
Fix more tests.
117
        self.head = head
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
118
        self.base = bzrdir.transport.base
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
119
0.200.293 by Jelmer Vernooij
Fix branch nicks.
120
    def _get_nick(self, local=False, possible_master_transports=None):
121
        """Find the nick name for this branch.
122
123
        :return: Branch nick
124
        """
125
        return self.name
126
0.200.331 by Jelmer Vernooij
Add stub for setting nick function.
127
    def _set_nick(self, nick):
128
        raise NotImplementedError
129
130
    nick = property(_get_nick, _set_nick)
0.200.293 by Jelmer Vernooij
Fix branch nicks.
131
0.200.211 by Jelmer Vernooij
Add basic infrastructure for dpush.
132
    def dpull(self, source, stop_revision=None):
133
        if stop_revision is None:
134
            stop_revision = source.last_revision()
135
        # FIXME: Check for diverged branches
136
        revidmap = self.repository.dfetch(source.repository, stop_revision)
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
137
        if revidmap != {}:
138
            self.generate_revision_history(revidmap[stop_revision])
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
139
        return revidmap
140
141
    def generate_revision_history(self, revid, old_revid=None):
142
        # FIXME: Check that old_revid is in the ancestry of revid
143
        newhead, self.mapping = self.mapping.revision_id_bzr_to_foreign(revid)
144
        self._set_head(newhead)
145
146
    def _set_head(self, head):
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
147
        self.head = head
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
148
        self.repository._git.set_ref(self.name, self.head)
0.200.211 by Jelmer Vernooij
Add basic infrastructure for dpush.
149
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
150
    def lock_write(self):
151
        self.control_files.lock_write()
152
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
153
    def get_stacked_on_url(self):
154
        # Git doesn't do stacking (yet...)
155
        return None
156
157
    def get_parent(self):
158
        """See Branch.get_parent()."""
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
159
        # FIXME: Set "origin" url from .git/config ?
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
160
        return None
161
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
162
    def set_parent(self, url):
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
163
        # FIXME: Set "origin" url in .git/config ?
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
164
        pass
165
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
166
    def lock_read(self):
167
        self.control_files.lock_read()
168
169
    def unlock(self):
170
        self.control_files.unlock()
171
172
    def get_physical_lock_status(self):
173
        return False
174
175
 
176
class LocalGitBranch(GitBranch):
0.200.261 by Jelmer Vernooij
More formatting fixes.
177
    """A local Git branch."""
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
178
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
179
    @needs_read_lock
180
    def last_revision(self):
181
        # perhaps should escape this ?
0.200.57 by Jelmer Vernooij
Fix more tests.
182
        if self.head is None:
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
183
            return revision.NULL_REVISION
0.200.112 by Jelmer Vernooij
Fix the build.
184
        return self.mapping.revision_id_foreign_to_bzr(self.head)
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
185
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
186
    def _get_checkout_format(self):
187
        """Return the most suitable metadir for a checkout of this branch.
188
        Weaves are used if this branch's repository uses weaves.
189
        """
190
        format = self.repository.bzrdir.checkout_metadir()
191
        format.set_branch_format(self._format)
192
        return format
193
0.200.261 by Jelmer Vernooij
More formatting fixes.
194
    def create_checkout(self, to_location, revision_id=None, lightweight=False,
195
        accelerator_tree=None, hardlink=False):
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
196
        if lightweight:
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
197
            t = transport.get_transport(to_location)
198
            t.ensure_base()
199
            format = self._get_checkout_format()
200
            checkout = format.initialize_on_transport(t)
201
            from_branch = branch.BranchReferenceFormat().initialize(checkout, 
202
                self)
203
            tree = checkout.create_workingtree(revision_id,
204
                from_branch=from_branch, hardlink=hardlink)
205
            return tree
206
        else:
207
            return self._create_heavyweight_checkout(to_location, revision_id,
0.200.261 by Jelmer Vernooij
More formatting fixes.
208
            hardlink)
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
209
210
    def _create_heavyweight_checkout(self, to_location, revision_id=None, 
211
                                     hardlink=False):
212
        """Create a new heavyweight checkout of this branch.
213
214
        :param to_location: URL of location to create the new checkout in.
215
        :param revision_id: Revision that should be the tip of the checkout.
216
        :param hardlink: Whether to hardlink
217
        :return: WorkingTree object of checkout.
218
        """
219
        checkout_branch = BzrDir.create_branch_convenience(
220
            to_location, force_new_tree=False, format=get_rich_root_format())
221
        checkout = checkout_branch.bzrdir
222
        checkout_branch.bind(self)
223
        # pull up to the specified revision_id to set the initial 
224
        # branch tip correctly, and seed it with history.
225
        checkout_branch.pull(self, stop_revision=revision_id)
226
        return checkout.create_workingtree(revision_id, hardlink=hardlink)
227
0.200.57 by Jelmer Vernooij
Fix more tests.
228
    def _gen_revision_history(self):
0.200.58 by Jelmer Vernooij
Fix remaining tests.
229
        if self.head is None:
230
            return []
0.200.261 by Jelmer Vernooij
More formatting fixes.
231
        ret = list(self.repository.iter_reverse_revision_history(
232
            self.last_revision()))
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
233
        ret.reverse()
0.200.57 by Jelmer Vernooij
Fix more tests.
234
        return ret
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
235
236
    def get_config(self):
237
        return GitBranchConfig(self)
238
239
    def get_push_location(self):
240
        """See Branch.get_push_location."""
241
        push_loc = self.get_config().get_user_option('push_location')
242
        return push_loc
243
244
    def set_push_location(self, location):
245
        """See Branch.set_push_location."""
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
246
        self.get_config().set_user_option('push_location', location,
0.217.54 by John Carr
set_user_option breaks - doesnt have a local option in BranchConfig. Follow the bzr.dev syntax instead.
247
                                          store=config.STORE_LOCATION)
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
248
249
    def supports_tags(self):
0.200.82 by Jelmer Vernooij
Support listing tags.
250
        return True
0.200.96 by Jelmer Vernooij
Fix branch.
251
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
252
0.200.342 by Jelmer Vernooij
Report git sha during pull.
253
class GitBranchPullResult(branch.PullResult):
254
255
    def report(self, to_file):
256
        if not is_quiet():
257
            if self.old_revid == self.new_revid:
258
                to_file.write('No revisions to pull.\n')
259
            else:
260
                to_file.write('Now on revision %d (git sha: %s).\n' % 
261
                        (self.new_revno, self.new_git_head))
262
        self._show_tag_conficts(to_file)
263
264
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
265
class InterGitGenericBranch(branch.InterBranch):
0.200.261 by Jelmer Vernooij
More formatting fixes.
266
    """InterBranch implementation that pulls from Git into bzr."""
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
267
268
    @classmethod
269
    def is_compatible(self, source, target):
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
270
        return (isinstance(source, GitBranch) and 
271
                not isinstance(target, GitBranch))
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
272
273
    def update_revisions(self, stop_revision=None, overwrite=False,
274
        graph=None):
275
        """See InterBranch.update_revisions()."""
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
276
        interrepo = repository.InterRepository.get(self.source.repository, 
277
            self.target.repository)
0.200.342 by Jelmer Vernooij
Report git sha during pull.
278
        self._head = None
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
279
        self._last_revid = None
280
        def determine_wants(heads):
281
            if not self.source.name in heads:
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
282
                raise NoSuchRef(self.source.name, heads.keys())
0.200.314 by Jelmer Vernooij
Support stop_revision.
283
            if stop_revision is not None:
284
                self._last_revid = stop_revision
0.200.342 by Jelmer Vernooij
Report git sha during pull.
285
                self._head, mapping = self.source.repository.lookup_git_revid(
0.200.316 by Jelmer Vernooij
Fix formatting.
286
                    stop_revision)
0.200.314 by Jelmer Vernooij
Support stop_revision.
287
            else:
0.200.342 by Jelmer Vernooij
Report git sha during pull.
288
                self._head = heads[self.source.name]
0.200.316 by Jelmer Vernooij
Fix formatting.
289
                self._last_revid = \
0.200.342 by Jelmer Vernooij
Report git sha during pull.
290
                    self.source.mapping.revision_id_foreign_to_bzr(self._head)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
291
            if self.target.repository.has_revision(self._last_revid):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
292
                return []
0.200.342 by Jelmer Vernooij
Report git sha during pull.
293
            return [self._head]
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
294
        interrepo.fetch_objects(determine_wants, self.source.mapping)
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
295
        if overwrite:
0.200.314 by Jelmer Vernooij
Support stop_revision.
296
            prev_last_revid = None
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
297
        else:
0.200.314 by Jelmer Vernooij
Support stop_revision.
298
            prev_last_revid = self.target.last_revision()
299
        self.target.generate_revision_history(self._last_revid, prev_last_revid)
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
300
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
301
    def pull(self, overwrite=False, stop_revision=None,
302
             possible_transports=None, _hook_master=None, run_hooks=True,
303
             _override_hook_target=None):
304
        """See Branch.pull.
305
306
        :param _hook_master: Private parameter - set the branch to
307
            be supplied as the master to pull hooks.
308
        :param run_hooks: Private parameter - if false, this branch
309
            is being called because it's the master of the primary branch,
310
            so it should not run its hooks.
311
        :param _override_hook_target: Private parameter - set the branch to be
312
            supplied as the target_branch to pull hooks.
313
        """
0.200.342 by Jelmer Vernooij
Report git sha during pull.
314
        result = GitBranchPullResult()
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
315
        result.source_branch = self.source
316
        if _override_hook_target is None:
317
            result.target_branch = self.target
318
        else:
319
            result.target_branch = _override_hook_target
320
        self.source.lock_read()
321
        try:
322
            # We assume that during 'pull' the target repository is closer than
323
            # the source one.
324
            graph = self.target.repository.get_graph(self.source.repository)
325
            result.old_revno, result.old_revid = \
326
                self.target.last_revision_info()
0.200.342 by Jelmer Vernooij
Report git sha during pull.
327
            self.update_revisions(stop_revision, overwrite=overwrite, 
328
                graph=graph)
329
            result.new_git_head = self._head
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
330
            result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
331
                overwrite)
332
            result.new_revno, result.new_revid = self.target.last_revision_info()
333
            if _hook_master:
334
                result.master_branch = _hook_master
335
                result.local_branch = result.target_branch
336
            else:
337
                result.master_branch = result.target_branch
338
                result.local_branch = None
339
            if run_hooks:
340
                for hook in branch.Branch.hooks['post_pull']:
341
                    hook(result)
342
        finally:
343
            self.source.unlock()
344
        return result
345
346
347
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
348
349
branch.InterBranch.register_optimiser(InterGitGenericBranch)
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
350
351
352
class InterGitRemoteLocalBranch(branch.InterBranch):
353
    """InterBranch implementation that pulls between Git branches."""
354
355
    @classmethod
356
    def is_compatible(self, source, target):
357
        from bzrlib.plugins.git.remote import RemoteGitBranch
358
        return (isinstance(source, RemoteGitBranch) and 
359
                isinstance(target, LocalGitBranch))
360
361
    def pull(self, stop_revision=None, overwrite=False, 
362
        possible_transports=None):
363
        result = GitPullResult()
364
        result.source_branch = self.source
365
        result.target_branch = self.target
366
        interrepo = repository.InterRepository.get(self.source.repository, 
367
            self.target.repository)
368
        result.old_revid = self.target.last_revision()
369
        if stop_revision is None:
370
            stop_revision = self.source.last_revision()
371
        interrepo.fetch(revision_id=stop_revision)
372
        self.target.generate_revision_history(stop_revision, result.old_revid)
373
        result.new_revid = self.target.last_revision()
374
        return result
375
376
377
branch.InterBranch.register_optimiser(InterGitRemoteLocalBranch)