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