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