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