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