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