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