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