/brz/remove-bazaar

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