/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,
0.200.513 by Jelmer Vernooij
Fix imports.
27
    bzrdir,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
28
    config,
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
29
    errors,
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
30
    repository,
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
31
    revision,
0.200.82 by Jelmer Vernooij
Support listing tags.
32
    tag,
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
33
    transport,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
34
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
35
from bzrlib.decorators import (
36
    needs_read_lock,
37
    )
38
from bzrlib.trace import (
0.200.342 by Jelmer Vernooij
Report git sha during pull.
39
    is_quiet,
0.200.261 by Jelmer Vernooij
More formatting fixes.
40
    mutter,
41
    )
42
0.200.513 by Jelmer Vernooij
Fix imports.
43
from bzrlib.plugins.git import (
44
    get_rich_root_format,
45
    )
0.200.386 by Jelmer Vernooij
Move config to a separate file, support BranchConfig.username().
46
from bzrlib.plugins.git.config import (
47
    GitBranchConfig,
48
    )
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
49
from bzrlib.plugins.git.errors import (
0.200.472 by Jelmer Vernooij
Fix printing error when user attempts to push into git.
50
    NoPushSupport,
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
51
    NoSuchRef,
52
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
53
0.238.5 by Jelmer Vernooij
Remove old backwards compatibility code.
54
from bzrlib.foreign import ForeignBranch
0.200.388 by Jelmer Vernooij
Support bzr 1.14 as well.
55
0.200.261 by Jelmer Vernooij
More formatting fixes.
56
0.200.462 by Jelmer Vernooij
Import tags when pulling.
57
def extract_tags(refs, mapping):
58
    ret = {}
59
    for k,v in refs.iteritems():
60
        if k.startswith("refs/tags/") and not k.endswith("^{}"):
61
            v = refs.get(k+"^{}", v)
62
            ret[k[len("refs/tags/"):]] = mapping.revision_id_foreign_to_bzr(v)
63
    return ret
64
65
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
66
class GitPullResult(branch.PullResult):
67
68
    def _lookup_revno(self, revid):
69
        assert isinstance(revid, str), "was %r" % revid
70
        # Try in source branch first, it'll be faster
71
        return self.target_branch.revision_id_to_revno(revid)
72
73
    @property
74
    def old_revno(self):
75
        return self._lookup_revno(self.old_revid)
76
77
    @property
78
    def new_revno(self):
79
        return self._lookup_revno(self.new_revid)
80
81
0.200.261 by Jelmer Vernooij
More formatting fixes.
82
class LocalGitTagDict(tag.BasicTags):
83
    """Dictionary with tags in a local repository."""
0.200.82 by Jelmer Vernooij
Support listing tags.
84
0.200.89 by Jelmer Vernooij
Support sprouting branches.
85
    def __init__(self, branch):
86
        self.branch = branch
87
        self.repository = branch.repository
0.200.82 by Jelmer Vernooij
Support listing tags.
88
89
    def get_tag_dict(self):
90
        ret = {}
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
91
        for k,v in self.repository._git.refs.as_dict("refs/tags").iteritems():
0.200.609 by Jelmer Vernooij
Cope with tags pointing at nonexisting objects.
92
            try:
93
                obj = self.repository._git.get_object(v)
94
            except KeyError:
95
                mutter("Tag %s points at unknown object %s, ignoring", v, obj)
96
                continue
0.200.194 by Jelmer Vernooij
Look for commit object in heavyweight tags.
97
            while isinstance(obj, Tag):
98
                v = obj.object[1]
99
                obj = self.repository._git.get_object(v)
100
            if not isinstance(obj, Commit):
0.200.261 by Jelmer Vernooij
More formatting fixes.
101
                mutter("Tag %s points at object %r that is not a commit, "
102
                       "ignoring", k, obj)
0.200.194 by Jelmer Vernooij
Look for commit object in heavyweight tags.
103
                continue
0.200.180 by Jelmer Vernooij
Simplify tag handling.
104
            ret[k] = self.branch.mapping.revision_id_foreign_to_bzr(v)
0.200.82 by Jelmer Vernooij
Support listing tags.
105
        return ret
106
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
107
    def set_tag(self, name, revid):
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
108
        self.repository._git.refs["refs/tags/%s" % name], _ = \
0.200.462 by Jelmer Vernooij
Import tags when pulling.
109
            self.branch.mapping.revision_id_bzr_to_foreign(revid)
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
110
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
111
0.239.1 by Jelmer Vernooij
Avoid re-connecting to fetch tags we already know.
112
class DictTagDict(LocalGitTagDict):
113
114
115
    def __init__(self, branch, tags):
116
        super(DictTagDict, self).__init__(branch)
117
        self._tags = tags
118
119
    def get_tag_dict(self):
120
        return self._tags
121
122
123
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
124
class GitBranchFormat(branch.BranchFormat):
125
0.200.70 by Jelmer Vernooij
Implement GitBranchFormat.get_format_description.
126
    def get_format_description(self):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
127
        return 'Git Branch'
128
0.200.82 by Jelmer Vernooij
Support listing tags.
129
    def supports_tags(self):
130
        return True
131
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
132
    def make_tags(self, branch):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
133
        if getattr(branch.repository, "get_refs", None) is not None:
134
            from bzrlib.plugins.git.remote import RemoteGitTagDict
135
            return RemoteGitTagDict(branch)
0.200.261 by Jelmer Vernooij
More formatting fixes.
136
        else:
137
            return LocalGitTagDict(branch)
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
138
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
139
0.200.388 by Jelmer Vernooij
Support bzr 1.14 as well.
140
class GitBranch(ForeignBranch):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
141
    """An adapter to git repositories for bzr Branch objects."""
142
0.239.1 by Jelmer Vernooij
Avoid re-connecting to fetch tags we already know.
143
    def __init__(self, bzrdir, repository, name, lockfiles, tagsdict=None):
0.200.82 by Jelmer Vernooij
Support listing tags.
144
        self.repository = repository
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
145
        self._format = GitBranchFormat()
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
146
        self.control_files = lockfiles
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
147
        self.bzrdir = bzrdir
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
148
        super(GitBranch, self).__init__(repository.get_mapping())
0.239.1 by Jelmer Vernooij
Avoid re-connecting to fetch tags we already know.
149
        if tagsdict is not None:
150
            self.tags = DictTagDict(self, tagsdict)
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
151
        self.name = name
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
152
        self._head = None
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
153
        self.base = bzrdir.transport.base
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
154
0.239.8 by Jelmer Vernooij
Support checkouts.
155
    def _get_checkout_format(self):
156
        """Return the most suitable metadir for a checkout of this branch.
157
        Weaves are used if this branch's repository uses weaves.
158
        """
159
        return get_rich_root_format()
160
0.238.3 by Jelmer Vernooij
Remove svn references, prefer git send format when submitting changes against a git branch.
161
    def get_child_submit_format(self):
162
        """Return the preferred format of submissions to this branch."""
163
        ret = self.get_config().get_user_option("child_submit_format")
164
        if ret is not None:
165
            return ret
166
        return "git"
167
0.200.293 by Jelmer Vernooij
Fix branch nicks.
168
    def _get_nick(self, local=False, possible_master_transports=None):
169
        """Find the nick name for this branch.
170
171
        :return: Branch nick
172
        """
173
        return self.name
174
0.200.331 by Jelmer Vernooij
Add stub for setting nick function.
175
    def _set_nick(self, nick):
176
        raise NotImplementedError
177
178
    nick = property(_get_nick, _set_nick)
0.200.293 by Jelmer Vernooij
Fix branch nicks.
179
0.200.412 by Jelmer Vernooij
Implement GitBranch.__repr__.
180
    def __repr__(self):
181
        return "%s(%r, %r)" % (self.__class__.__name__, self.repository.base, self.name)
182
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
183
    def generate_revision_history(self, revid, old_revid=None):
184
        # FIXME: Check that old_revid is in the ancestry of revid
185
        newhead, self.mapping = self.mapping.revision_id_bzr_to_foreign(revid)
186
        self._set_head(newhead)
187
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
188
    def lock_write(self):
189
        self.control_files.lock_write()
190
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
191
    def get_stacked_on_url(self):
192
        # Git doesn't do stacking (yet...)
193
        return None
194
195
    def get_parent(self):
196
        """See Branch.get_parent()."""
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
197
        # 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.
198
        return None
199
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
200
    def set_parent(self, url):
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
201
        # FIXME: Set "origin" url in .git/config ?
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
202
        pass
203
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
204
    def lock_read(self):
205
        self.control_files.lock_read()
206
0.200.432 by Jelmer Vernooij
Support Branch.is_locked, required for loggerhead.
207
    def is_locked(self):
208
        return self.control_files.is_locked()
209
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
210
    def unlock(self):
211
        self.control_files.unlock()
212
213
    def get_physical_lock_status(self):
214
        return False
215
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
216
    @needs_read_lock
217
    def last_revision(self):
218
        # perhaps should escape this ?
0.200.57 by Jelmer Vernooij
Fix more tests.
219
        if self.head is None:
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
220
            return revision.NULL_REVISION
0.200.112 by Jelmer Vernooij
Fix the build.
221
        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.
222
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
223
    def _basic_push(self, target, overwrite=False, stop_revision=None):
224
        return branch.InterBranch.get(self, target)._basic_push(
225
            overwrite, stop_revision)
226
0.200.465 by Jelmer Vernooij
Use dulwich standard functionality for finding missing revisions.
227
 
228
class LocalGitBranch(GitBranch):
229
    """A local Git branch."""
230
0.200.261 by Jelmer Vernooij
More formatting fixes.
231
    def create_checkout(self, to_location, revision_id=None, lightweight=False,
232
        accelerator_tree=None, hardlink=False):
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
233
        if lightweight:
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
234
            t = transport.get_transport(to_location)
235
            t.ensure_base()
236
            format = self._get_checkout_format()
237
            checkout = format.initialize_on_transport(t)
238
            from_branch = branch.BranchReferenceFormat().initialize(checkout, 
239
                self)
240
            tree = checkout.create_workingtree(revision_id,
241
                from_branch=from_branch, hardlink=hardlink)
242
            return tree
243
        else:
244
            return self._create_heavyweight_checkout(to_location, revision_id,
0.200.261 by Jelmer Vernooij
More formatting fixes.
245
            hardlink)
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
246
247
    def _create_heavyweight_checkout(self, to_location, revision_id=None, 
248
                                     hardlink=False):
249
        """Create a new heavyweight checkout of this branch.
250
251
        :param to_location: URL of location to create the new checkout in.
252
        :param revision_id: Revision that should be the tip of the checkout.
253
        :param hardlink: Whether to hardlink
254
        :return: WorkingTree object of checkout.
255
        """
0.200.513 by Jelmer Vernooij
Fix imports.
256
        checkout_branch = bzrdir.BzrDir.create_branch_convenience(
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
257
            to_location, force_new_tree=False, format=get_rich_root_format())
258
        checkout = checkout_branch.bzrdir
259
        checkout_branch.bind(self)
260
        # pull up to the specified revision_id to set the initial 
261
        # branch tip correctly, and seed it with history.
262
        checkout_branch.pull(self, stop_revision=revision_id)
263
        return checkout.create_workingtree(revision_id, hardlink=hardlink)
264
0.200.57 by Jelmer Vernooij
Fix more tests.
265
    def _gen_revision_history(self):
0.200.58 by Jelmer Vernooij
Fix remaining tests.
266
        if self.head is None:
267
            return []
0.200.261 by Jelmer Vernooij
More formatting fixes.
268
        ret = list(self.repository.iter_reverse_revision_history(
269
            self.last_revision()))
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
270
        ret.reverse()
0.200.57 by Jelmer Vernooij
Fix more tests.
271
        return ret
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
272
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
273
    def _get_head(self):
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
274
        try:
275
            return self.repository._git.ref(self.name)
276
        except KeyError:
277
            return None
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
278
0.200.507 by Jelmer Vernooij
Implement set_last_revision{_info,}.
279
    def set_last_revision_info(self, revno, revid):
280
        self.set_last_revision(revid)
281
282
    def set_last_revision(self, revid):
0.200.523 by Jelmer Vernooij
Fix undefined error.
283
        (newhead, self.mapping) = self.mapping.revision_id_bzr_to_foreign(
0.200.507 by Jelmer Vernooij
Implement set_last_revision{_info,}.
284
                revid)
0.200.523 by Jelmer Vernooij
Fix undefined error.
285
        self.head = newhead
0.200.507 by Jelmer Vernooij
Implement set_last_revision{_info,}.
286
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
287
    def _set_head(self, value):
288
        self._head = value
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
289
        self.repository._git.refs[self.name] = self._head
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
290
        self._clear_cached_state()
291
292
    head = property(_get_head, _set_head)
293
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
294
    def get_config(self):
295
        return GitBranchConfig(self)
296
297
    def get_push_location(self):
298
        """See Branch.get_push_location."""
299
        push_loc = self.get_config().get_user_option('push_location')
300
        return push_loc
301
302
    def set_push_location(self, location):
303
        """See Branch.set_push_location."""
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
304
        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.
305
                                          store=config.STORE_LOCATION)
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
306
307
    def supports_tags(self):
0.200.82 by Jelmer Vernooij
Support listing tags.
308
        return True
0.200.96 by Jelmer Vernooij
Fix branch.
309
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
310
0.200.342 by Jelmer Vernooij
Report git sha during pull.
311
class GitBranchPullResult(branch.PullResult):
312
313
    def report(self, to_file):
314
        if not is_quiet():
315
            if self.old_revid == self.new_revid:
316
                to_file.write('No revisions to pull.\n')
317
            else:
318
                to_file.write('Now on revision %d (git sha: %s).\n' % 
319
                        (self.new_revno, self.new_git_head))
320
        self._show_tag_conficts(to_file)
321
322
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
323
class GitBranchPushResult(branch.BranchPushResult):
324
325
    def _lookup_revno(self, revid):
326
        assert isinstance(revid, str), "was %r" % revid
327
        # Try in source branch first, it'll be faster
328
        try:
329
            return self.source_branch.revision_id_to_revno(revid)
0.200.523 by Jelmer Vernooij
Fix undefined error.
330
        except errors.NoSuchRevision:
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
331
            # FIXME: Check using graph.find_distance_to_null() ?
332
            return self.target_branch.revision_id_to_revno(revid)
333
334
    @property
335
    def old_revno(self):
336
        return self._lookup_revno(self.old_revid)
337
338
    @property
339
    def new_revno(self):
340
        return self._lookup_revno(self.new_revid)
341
342
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
343
class InterFromGitBranch(branch.GenericInterBranch):
0.200.261 by Jelmer Vernooij
More formatting fixes.
344
    """InterBranch implementation that pulls from Git into bzr."""
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
345
346
    @classmethod
347
    def is_compatible(self, source, target):
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
348
        return (isinstance(source, GitBranch) and 
349
                not isinstance(target, GitBranch))
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
350
351
    def update_revisions(self, stop_revision=None, overwrite=False,
352
        graph=None):
353
        """See InterBranch.update_revisions()."""
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
354
        interrepo = repository.InterRepository.get(self.source.repository, 
355
            self.target.repository)
0.200.342 by Jelmer Vernooij
Report git sha during pull.
356
        self._head = None
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
357
        self._last_revid = None
358
        def determine_wants(heads):
359
            if not self.source.name in heads:
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
360
                raise NoSuchRef(self.source.name, heads.keys())
0.200.314 by Jelmer Vernooij
Support stop_revision.
361
            if stop_revision is not None:
362
                self._last_revid = stop_revision
0.200.342 by Jelmer Vernooij
Report git sha during pull.
363
                self._head, mapping = self.source.repository.lookup_git_revid(
0.200.316 by Jelmer Vernooij
Fix formatting.
364
                    stop_revision)
0.200.314 by Jelmer Vernooij
Support stop_revision.
365
            else:
0.200.342 by Jelmer Vernooij
Report git sha during pull.
366
                self._head = heads[self.source.name]
0.200.316 by Jelmer Vernooij
Fix formatting.
367
                self._last_revid = \
0.200.342 by Jelmer Vernooij
Report git sha during pull.
368
                    self.source.mapping.revision_id_foreign_to_bzr(self._head)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
369
            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.
370
                return []
0.200.342 by Jelmer Vernooij
Report git sha during pull.
371
            return [self._head]
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
372
        interrepo.fetch_objects(determine_wants, self.source.mapping)
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
373
        if overwrite:
0.200.314 by Jelmer Vernooij
Support stop_revision.
374
            prev_last_revid = None
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
375
        else:
0.200.314 by Jelmer Vernooij
Support stop_revision.
376
            prev_last_revid = self.target.last_revision()
377
        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.
378
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
379
    def pull(self, overwrite=False, stop_revision=None,
380
             possible_transports=None, _hook_master=None, run_hooks=True,
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
381
             _override_hook_target=None, local=False):
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
382
        """See Branch.pull.
383
384
        :param _hook_master: Private parameter - set the branch to
385
            be supplied as the master to pull hooks.
386
        :param run_hooks: Private parameter - if false, this branch
387
            is being called because it's the master of the primary branch,
388
            so it should not run its hooks.
389
        :param _override_hook_target: Private parameter - set the branch to be
390
            supplied as the target_branch to pull hooks.
391
        """
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
392
        # This type of branch can't be bound.
393
        if local:
394
            raise errors.LocalRequiresBoundBranch()
0.200.342 by Jelmer Vernooij
Report git sha during pull.
395
        result = GitBranchPullResult()
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
396
        result.source_branch = self.source
397
        if _override_hook_target is None:
398
            result.target_branch = self.target
399
        else:
400
            result.target_branch = _override_hook_target
401
        self.source.lock_read()
402
        try:
403
            # We assume that during 'pull' the target repository is closer than
404
            # the source one.
405
            graph = self.target.repository.get_graph(self.source.repository)
406
            result.old_revno, result.old_revid = \
407
                self.target.last_revision_info()
0.200.342 by Jelmer Vernooij
Report git sha during pull.
408
            self.update_revisions(stop_revision, overwrite=overwrite, 
409
                graph=graph)
410
            result.new_git_head = self._head
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
411
            result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
412
                overwrite)
413
            result.new_revno, result.new_revid = self.target.last_revision_info()
414
            if _hook_master:
415
                result.master_branch = _hook_master
416
                result.local_branch = result.target_branch
417
            else:
418
                result.master_branch = result.target_branch
419
                result.local_branch = None
420
            if run_hooks:
421
                for hook in branch.Branch.hooks['post_pull']:
422
                    hook(result)
423
        finally:
424
            self.source.unlock()
425
        return result
426
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
427
    def _basic_push(self, overwrite=False, stop_revision=None):
428
        result = branch.BranchPushResult()
429
        result.source_branch = self.source
430
        result.target_branch = self.target
0.200.505 by Jelmer Vernooij
Remove duplicate code.
431
        graph = self.target.repository.get_graph(self.source.repository)
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
432
        result.old_revno, result.old_revid = self.target.last_revision_info()
433
        self.update_revisions(stop_revision, overwrite=overwrite, 
434
            graph=graph)
435
        result.new_git_head = self._head
436
        result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
437
            overwrite)
438
        result.new_revno, result.new_revid = self.target.last_revision_info()
439
        return result
440
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
441
0.200.512 by Jelmer Vernooij
Support pushing git->git.
442
class InterGitBranch(branch.GenericInterBranch):
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
443
    """InterBranch implementation that pulls between Git branches."""
444
0.200.512 by Jelmer Vernooij
Support pushing git->git.
445
446
class InterGitLocalRemoteBranch(InterGitBranch):
447
    """InterBranch that copies from a local to a remote git branch."""
448
449
    @classmethod
450
    def is_compatible(self, source, target):
451
        from bzrlib.plugins.git.remote import RemoteGitBranch
452
        return (isinstance(source, LocalGitBranch) and 
453
                isinstance(target, RemoteGitBranch))
454
455
    def _basic_push(self, overwrite=False, stop_revision=None):
456
        result = GitBranchPushResult()
457
        result.source_branch = self.source
458
        result.target_branch = self.target
459
        if stop_revision is None:
460
            stop_revision = self.source.last_revision()
461
        # FIXME: Check for diverged branches
462
        def get_changed_refs(old_refs):
0.200.544 by Jelmer Vernooij
Support pushing from git -> empty git repo.
463
            result.old_revid = self.target.mapping.revision_id_foreign_to_bzr(old_refs.get("refs/heads/master", "0" * 40))
0.200.512 by Jelmer Vernooij
Support pushing git->git.
464
            refs = { "refs/heads/master": self.source.repository.lookup_git_revid(stop_revision)[0] }
465
            result.new_revid = stop_revision
466
            for name, sha in self.source.repository._git.refs.as_dict("refs/tags").iteritems():
467
                refs["refs/tags/%s" % name] = sha
468
            return refs
469
        self.target.repository.send_pack(get_changed_refs, 
470
                self.source.repository._git.object_store.generate_pack_contents)
471
        return result
472
473
474
class InterGitRemoteLocalBranch(InterGitBranch):
475
    """InterBranch that copies from a remote to a local git branch."""
476
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
477
    @classmethod
478
    def is_compatible(self, source, target):
479
        from bzrlib.plugins.git.remote import RemoteGitBranch
480
        return (isinstance(source, RemoteGitBranch) and 
481
                isinstance(target, LocalGitBranch))
482
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
483
    def _basic_push(self, overwrite=False, stop_revision=None):
484
        result = branch.BranchPushResult()
485
        result.source_branch = self.source
486
        result.target_branch = self.target
487
        result.old_revid = self.target.last_revision()
488
        refs, stop_revision = self.update_refs(stop_revision)
489
        self.target.generate_revision_history(stop_revision, result.old_revid)
490
        self.update_tags(refs)
0.200.505 by Jelmer Vernooij
Remove duplicate code.
491
        result.new_revid = self.target.last_revision()
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
492
        return result
493
494
    def update_tags(self, refs):
495
        for name, revid in extract_tags(refs, self.target.mapping).iteritems():
496
            self.target.tags.set_tag(name, revid)
497
498
    def update_refs(self, stop_revision=None):
499
        interrepo = repository.InterRepository.get(self.source.repository, 
500
            self.target.repository)
501
        if stop_revision is None:
502
            refs = interrepo.fetch_refs(branches=["HEAD"])
503
            stop_revision = self.target.mapping.revision_id_foreign_to_bzr(refs["HEAD"])
504
        else:
505
            refs = interrepo.fetch_refs(revision_id=stop_revision)
506
        return refs, stop_revision
507
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
508
    def pull(self, stop_revision=None, overwrite=False, 
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
509
        possible_transports=None, local=False):
510
        # This type of branch can't be bound.
511
        if local:
512
            raise errors.LocalRequiresBoundBranch()
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
513
        result = GitPullResult()
514
        result.source_branch = self.source
515
        result.target_branch = self.target
516
        result.old_revid = self.target.last_revision()
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
517
        refs, stop_revision = self.update_refs(stop_revision)
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
518
        self.target.generate_revision_history(stop_revision, result.old_revid)
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
519
        self.update_tags(refs)
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
520
        result.new_revid = self.target.last_revision()
521
        return result
522
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
523
    
524
class InterToGitBranch(branch.InterBranch):
525
    """InterBranch implementation that pulls from Git into bzr."""
526
527
    @classmethod
528
    def is_compatible(self, source, target):
529
        return (not isinstance(source, GitBranch) and 
530
                isinstance(target, GitBranch))
531
0.200.542 by Jelmer Vernooij
Proper error for push in 1.14.
532
    def update_revisions(self, *args, **kwargs):
533
        raise NoPushSupport()
534
0.200.472 by Jelmer Vernooij
Fix printing error when user attempts to push into git.
535
    def push(self, overwrite=True, stop_revision=None, 
536
             _override_hook_source_branch=None):
537
        raise NoPushSupport()
538
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
539
    def lossy_push(self, stop_revision=None):
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
540
        result = GitBranchPushResult()
0.200.503 by Jelmer Vernooij
Remove dpull, return BranchPushResult in lossy_push.
541
        result.source_branch = self.source
542
        result.target_branch = self.target
0.239.14 by Jelmer Vernooij
Cope with pushing to (not yet) existing branches.
543
        try:
544
            result.old_revid = self.target.last_revision()
545
        except NoSuchRef:
546
            result.old_revid = revision.NULL_REVISION
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
547
        if stop_revision is None:
548
            stop_revision = self.source.last_revision()
549
        # FIXME: Check for diverged branches
550
        refs = { "refs/heads/master": stop_revision }
551
        for name, revid in self.source.tags.get_tag_dict().iteritems():
552
            if self.source.repository.has_revision(revid):
553
                refs["refs/tags/%s" % name] = revid
554
        revidmap, new_refs = self.target.repository.dfetch_refs(
555
            self.source.repository, refs)
556
        if revidmap != {}:
557
            self.target.generate_revision_history(revidmap[stop_revision])
0.200.520 by Jelmer Vernooij
Proper output from dpush.
558
            result.new_revid = revidmap[stop_revision]
559
        else:
560
            result.new_revid = result.old_revid
0.200.503 by Jelmer Vernooij
Remove dpull, return BranchPushResult in lossy_push.
561
        result.revidmap = revidmap
562
        return result
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
563
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
564
565
branch.InterBranch.register_optimiser(InterGitRemoteLocalBranch)
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
566
branch.InterBranch.register_optimiser(InterFromGitBranch)
567
branch.InterBranch.register_optimiser(InterToGitBranch)
0.200.512 by Jelmer Vernooij
Support pushing git->git.
568
branch.InterBranch.register_optimiser(InterGitLocalRemoteBranch)