/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.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
20
from collections import defaultdict
21
0.200.261 by Jelmer Vernooij
More formatting fixes.
22
from dulwich.objects import (
23
    Commit,
24
    Tag,
0.200.1153 by Jelmer Vernooij
Import ZERO_SHA from dulwich.objects.
25
    ZERO_SHA,
0.200.261 by Jelmer Vernooij
More formatting fixes.
26
    )
27
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
28
from bzrlib import (
29
    branch,
0.200.513 by Jelmer Vernooij
Fix imports.
30
    bzrdir,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
31
    config,
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
32
    errors,
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
33
    repository as _mod_repository,
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
34
    revision,
0.200.82 by Jelmer Vernooij
Support listing tags.
35
    tag,
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
36
    transport,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
37
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
38
from bzrlib.decorators import (
39
    needs_read_lock,
40
    )
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
41
from bzrlib.revision import (
42
    NULL_REVISION,
43
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
44
from bzrlib.trace import (
0.200.342 by Jelmer Vernooij
Report git sha during pull.
45
    is_quiet,
0.200.261 by Jelmer Vernooij
More formatting fixes.
46
    mutter,
47
    )
48
0.200.386 by Jelmer Vernooij
Move config to a separate file, support BranchConfig.username().
49
from bzrlib.plugins.git.config import (
50
    GitBranchConfig,
51
    )
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
52
from bzrlib.plugins.git.errors import (
0.200.472 by Jelmer Vernooij
Fix printing error when user attempts to push into git.
53
    NoPushSupport,
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
54
    NoSuchRef,
55
    )
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
56
from bzrlib.plugins.git.refs import (
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
57
    branch_name_to_ref,
0.200.1061 by Jelmer Vernooij
Add support for using unpeel map.
58
    extract_tags,
59
    is_tag,
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
60
    ref_to_branch_name,
0.200.1061 by Jelmer Vernooij
Add support for using unpeel map.
61
    ref_to_tag_name,
0.200.875 by Jelmer Vernooij
Use new tag_name_to_ref function.
62
    tag_name_to_ref,
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
63
    )
64
from bzrlib.plugins.git.unpeel_map import (
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
65
    UnpeelMap,
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
66
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
67
0.238.5 by Jelmer Vernooij
Remove old backwards compatibility code.
68
from bzrlib.foreign import ForeignBranch
0.200.388 by Jelmer Vernooij
Support bzr 1.14 as well.
69
0.200.261 by Jelmer Vernooij
More formatting fixes.
70
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
71
class GitPullResult(branch.PullResult):
0.200.956 by Jelmer Vernooij
Add some more format tests.
72
    """Result of a pull from a Git branch."""
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
73
74
    def _lookup_revno(self, revid):
75
        assert isinstance(revid, str), "was %r" % revid
76
        # Try in source branch first, it'll be faster
77
        return self.target_branch.revision_id_to_revno(revid)
78
79
    @property
80
    def old_revno(self):
81
        return self._lookup_revno(self.old_revid)
82
83
    @property
84
    def new_revno(self):
85
        return self._lookup_revno(self.new_revid)
86
87
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
88
class GitTags(tag.BasicTags):
89
    """Ref-based tag dictionary."""
0.200.82 by Jelmer Vernooij
Support listing tags.
90
0.200.89 by Jelmer Vernooij
Support sprouting branches.
91
    def __init__(self, branch):
92
        self.branch = branch
93
        self.repository = branch.repository
0.200.82 by Jelmer Vernooij
Support listing tags.
94
0.200.1066 by Jelmer Vernooij
Add GitTags.get_refs.
95
    def get_refs(self):
96
        raise NotImplementedError(self.get_refs)
97
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
98
    def _iter_tag_refs(self, refs):
99
        raise NotImplementedError(self._iter_tag_refs)
100
101
    def _merge_to_git(self, to_tags, refs, overwrite=False):
102
        target_repo = to_tags.repository
103
        conflicts = []
104
        for k, v in refs.iteritems():
105
            if not is_tag(k):
106
                continue
0.200.1128 by Jelmer Vernooij
remove duplicate definition of _matchingbzrdir.
107
            if overwrite or not k in target_repo._git.refs:
108
                target_repo._git.refs[k] = v
109
            elif target_repo._git.refs[k] == v:
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
110
                pass
111
            else:
112
                conflicts.append((ref_to_tag_name(k), v, target_repo.refs[k]))
113
        return conflicts
114
115
    def _merge_to_non_git(self, to_tags, refs, overwrite=False):
116
        unpeeled_map = defaultdict(set)
117
        conflicts = []
118
        result = dict(to_tags.get_tag_dict())
119
        for n, peeled, unpeeled, bzr_revid in self._iter_tag_refs(refs):
120
            if unpeeled is not None:
121
                unpeeled_map[peeled].add(unpeeled)
122
            if n not in result or overwrite:
123
                result[n] = bzr_revid
124
            elif result[n] == bzr_revid:
125
                pass
126
            else:
127
                conflicts.append((n, result[n], bzr_revid))
128
        to_tags._set_tag_dict(result)
129
        if len(unpeeled_map) > 0:
130
            map_file = UnpeelMap.from_repository(to_tags.branch.repository)
131
            map_file.update(unpeeled_map)
132
            map_file.save_in_repository(to_tags.branch.repository)
133
        return conflicts
134
135
    def merge_to(self, to_tags, overwrite=False, ignore_master=False,
136
                 source_refs=None):
0.200.1113 by Jelmer Vernooij
Fix Tags.merge_to.
137
        """See Tags.merge_to."""
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
138
        if source_refs is None:
0.200.1066 by Jelmer Vernooij
Add GitTags.get_refs.
139
            source_refs = self.get_refs()
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
140
        if self == to_tags:
141
            return
142
        if isinstance(to_tags, GitTags):
143
            return self._merge_to_git(to_tags, source_refs,
144
                                      overwrite=overwrite)
145
        else:
146
            if ignore_master:
147
                master = None
148
            else:
149
                master = to_tags.branch.get_master_branch()
150
            conflicts = self._merge_to_non_git(to_tags, source_refs,
151
                                              overwrite=overwrite)
152
            if master is not None:
0.200.1113 by Jelmer Vernooij
Fix Tags.merge_to.
153
                conflicts += self.merge_to(master.tags, overwrite=overwrite,
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
154
                                           source_refs=source_refs,
155
                                           ignore_master=ignore_master)
156
            return conflicts
157
158
    def get_tag_dict(self):
159
        ret = {}
0.200.1066 by Jelmer Vernooij
Add GitTags.get_refs.
160
        refs = self.get_refs()
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
161
        for (name, peeled, unpeeled, bzr_revid) in self._iter_tag_refs(refs):
162
            ret[name] = bzr_revid
163
        return ret
164
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
165
166
class LocalGitTagDict(GitTags):
167
    """Dictionary with tags in a local repository."""
168
169
    def __init__(self, branch):
170
        super(LocalGitTagDict, self).__init__(branch)
171
        self.refs = self.repository._git.refs
172
0.200.1066 by Jelmer Vernooij
Add GitTags.get_refs.
173
    def get_refs(self):
174
        return self.repository._git.get_refs()
175
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
176
    def _iter_tag_refs(self, refs):
177
        """Iterate over the tag refs.
178
179
        :param refs: Refs dictionary (name -> git sha1)
180
        :return: iterator over (name, peeled_sha1, unpeeled_sha1, bzr_revid)
181
        """
0.200.1060 by Jelmer Vernooij
Return unpeeled tags in extract_tags.
182
        for k, (peeled, unpeeled) in extract_tags(refs).iteritems():
0.200.609 by Jelmer Vernooij
Cope with tags pointing at nonexisting objects.
183
            try:
0.200.1060 by Jelmer Vernooij
Return unpeeled tags in extract_tags.
184
                obj = self.repository._git[peeled]
0.200.609 by Jelmer Vernooij
Cope with tags pointing at nonexisting objects.
185
            except KeyError:
0.200.1060 by Jelmer Vernooij
Return unpeeled tags in extract_tags.
186
                mutter("Tag %s points at unknown object %s, ignoring", peeled,
0.200.1320 by Jelmer Vernooij
Fix trace.
187
                       peeled)
0.200.609 by Jelmer Vernooij
Cope with tags pointing at nonexisting objects.
188
                continue
0.200.1060 by Jelmer Vernooij
Return unpeeled tags in extract_tags.
189
            # FIXME: this shouldn't really be necessary, the repository
190
            # already should have these unpeeled.
0.200.194 by Jelmer Vernooij
Look for commit object in heavyweight tags.
191
            while isinstance(obj, Tag):
0.200.1060 by Jelmer Vernooij
Return unpeeled tags in extract_tags.
192
                peeled = obj.object[1]
193
                obj = self.repository._git[peeled]
0.200.194 by Jelmer Vernooij
Look for commit object in heavyweight tags.
194
            if not isinstance(obj, Commit):
0.200.261 by Jelmer Vernooij
More formatting fixes.
195
                mutter("Tag %s points at object %r that is not a commit, "
196
                       "ignoring", k, obj)
0.200.194 by Jelmer Vernooij
Look for commit object in heavyweight tags.
197
                continue
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
198
            yield (k, peeled, unpeeled,
199
                   self.branch.lookup_foreign_revision_id(peeled))
200
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
201
    def _set_tag_dict(self, to_dict):
0.200.1066 by Jelmer Vernooij
Add GitTags.get_refs.
202
        extra = set(self.get_refs().keys())
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
203
        for k, revid in to_dict.iteritems():
0.200.875 by Jelmer Vernooij
Use new tag_name_to_ref function.
204
            name = tag_name_to_ref(k)
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
205
            if name in extra:
206
                extra.remove(name)
207
            self.set_tag(k, revid)
208
        for name in extra:
0.200.1061 by Jelmer Vernooij
Add support for using unpeel map.
209
            if is_tag(name):
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
210
                del self.repository._git[name]
0.200.956 by Jelmer Vernooij
Add some more format tests.
211
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
212
    def set_tag(self, name, revid):
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
213
        self.refs[tag_name_to_ref(name)], _ = \
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
214
            self.branch.lookup_bzr_revision_id(revid)
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
215
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
216
0.200.1078 by Jelmer Vernooij
Fix git-import from remote repositories.
217
class DictTagDict(tag.BasicTags):
0.239.1 by Jelmer Vernooij
Avoid re-connecting to fetch tags we already know.
218
219
    def __init__(self, branch, tags):
220
        super(DictTagDict, self).__init__(branch)
221
        self._tags = tags
222
223
    def get_tag_dict(self):
224
        return self._tags
225
226
0.200.1311 by Jelmer Vernooij
More work on colocated branch support.
227
class GitSymrefBranchFormat(branch.BranchFormat):
228
229
    def get_format_description(self):
230
        return 'Git Symbolic Reference Branch'
231
232
    def network_name(self):
233
        return "git"
234
235
    def get_reference(self, controldir, name=None):
236
        return controldir.get_branch_reference(name)
237
238
    def set_reference(self, controldir, name, target):
239
        return controldir.set_branch_reference(name, target)
240
241
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
242
class GitBranchFormat(branch.BranchFormat):
243
0.200.70 by Jelmer Vernooij
Implement GitBranchFormat.get_format_description.
244
    def get_format_description(self):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
245
        return 'Git Branch'
246
0.243.1 by Jelmer Vernooij
Use foreign branch testing infrastructure.
247
    def network_name(self):
248
        return "git"
249
0.200.82 by Jelmer Vernooij
Support listing tags.
250
    def supports_tags(self):
251
        return True
252
0.200.1105 by Jelmer Vernooij
Don't claim to support leaving locks.
253
    def supports_leaving_lock(self):
254
        return False
255
0.200.1091 by Jelmer Vernooij
Provide _matchingbzrdir for testing.
256
    @property
257
    def _matchingbzrdir(self):
0.200.1140 by Jelmer Vernooij
Update now that the control dir formats are no longer in __init__.
258
        from bzrlib.plugins.git.dir import LocalGitControlDirFormat
0.200.1091 by Jelmer Vernooij
Provide _matchingbzrdir for testing.
259
        return LocalGitControlDirFormat()
260
0.243.1 by Jelmer Vernooij
Use foreign branch testing infrastructure.
261
    def get_foreign_tests_branch_factory(self):
262
        from bzrlib.plugins.git.tests.test_branch import ForeignTestsBranchFactory
263
        return ForeignTestsBranchFactory()
264
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
265
    def make_tags(self, branch):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
266
        if getattr(branch.repository, "get_refs", None) is not None:
267
            from bzrlib.plugins.git.remote import RemoteGitTagDict
268
            return RemoteGitTagDict(branch)
0.200.261 by Jelmer Vernooij
More formatting fixes.
269
        else:
270
            return LocalGitTagDict(branch)
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
271
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
272
    def initialize(self, a_bzrdir, name=None, repository=None):
273
        from bzrlib.plugins.git.dir import LocalGitDir
274
        if not isinstance(a_bzrdir, LocalGitDir):
275
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
276
        if repository is None:
277
            repository = a_bzrdir.open_repository()
0.200.1102 by Jelmer Vernooij
Fix creating of colocated branches in git repositories.
278
        ref = branch_name_to_ref(name, "HEAD")
279
        repository._git[ref] = ZERO_SHA
280
        return LocalGitBranch(a_bzrdir, repository, ref, a_bzrdir._lockfiles)
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
281
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
282
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
283
class GitReadLock(object):
284
285
    def __init__(self, unlock):
286
        self.unlock = unlock
287
288
289
class GitWriteLock(object):
290
291
    def __init__(self, unlock):
0.200.1175 by Jelmer Vernooij
Provide GitWriteLock.branch_token.
292
        self.branch_token = None
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
293
        self.unlock = unlock
294
295
0.200.388 by Jelmer Vernooij
Support bzr 1.14 as well.
296
class GitBranch(ForeignBranch):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
297
    """An adapter to git repositories for bzr Branch objects."""
298
0.200.1129 by Jelmer Vernooij
Implement GitBranch.control_transport.
299
    @property
300
    def control_transport(self):
301
        return self.bzrdir.control_transport
302
0.200.770 by Jelmer Vernooij
Proper branch names.
303
    def __init__(self, bzrdir, repository, ref, lockfiles, tagsdict=None):
0.200.1287 by Jelmer Vernooij
Set Branch.base before invoking branch open hooks.
304
        self.base = bzrdir.root_transport.base
0.200.82 by Jelmer Vernooij
Support listing tags.
305
        self.repository = repository
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
306
        self._format = GitBranchFormat()
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
307
        self.control_files = lockfiles
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
308
        self.bzrdir = bzrdir
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
309
        self._lock_mode = None
310
        self._lock_count = 0
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
311
        super(GitBranch, self).__init__(repository.get_mapping())
0.239.1 by Jelmer Vernooij
Avoid re-connecting to fetch tags we already know.
312
        if tagsdict is not None:
313
            self.tags = DictTagDict(self, tagsdict)
0.200.770 by Jelmer Vernooij
Proper branch names.
314
        self.ref = ref
0.200.1361 by Jelmer Vernooij
Support branches where the ref can't be mapped back to a branch name.
315
        try:
316
            self.name = ref_to_branch_name(ref)
317
        except ValueError:
318
            self.name = None
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
319
        self._head = None
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
320
0.200.1360 by Jelmer Vernooij
Support lighweight argument to _get_checkout_format.
321
    def _get_checkout_format(self, lightweight=False):
0.239.8 by Jelmer Vernooij
Support checkouts.
322
        """Return the most suitable metadir for a checkout of this branch.
323
        Weaves are used if this branch's repository uses weaves.
324
        """
0.200.927 by Jelmer Vernooij
Remove explicit use of rich root formats.
325
        return bzrdir.format_registry.make_bzrdir("default")
0.239.8 by Jelmer Vernooij
Support checkouts.
326
0.238.3 by Jelmer Vernooij
Remove svn references, prefer git send format when submitting changes against a git branch.
327
    def get_child_submit_format(self):
328
        """Return the preferred format of submissions to this branch."""
329
        ret = self.get_config().get_user_option("child_submit_format")
330
        if ret is not None:
331
            return ret
332
        return "git"
333
0.200.293 by Jelmer Vernooij
Fix branch nicks.
334
    def _get_nick(self, local=False, possible_master_transports=None):
335
        """Find the nick name for this branch.
336
337
        :return: Branch nick
338
        """
0.200.920 by Jelmer Vernooij
Fix some more tests.
339
        return self.name or "HEAD"
0.200.293 by Jelmer Vernooij
Fix branch nicks.
340
0.200.331 by Jelmer Vernooij
Add stub for setting nick function.
341
    def _set_nick(self, nick):
342
        raise NotImplementedError
343
344
    nick = property(_get_nick, _set_nick)
0.200.293 by Jelmer Vernooij
Fix branch nicks.
345
0.200.412 by Jelmer Vernooij
Implement GitBranch.__repr__.
346
    def __repr__(self):
0.200.770 by Jelmer Vernooij
Proper branch names.
347
        return "<%s(%r, %r)>" % (self.__class__.__name__, self.repository.base,
0.200.1311 by Jelmer Vernooij
More work on colocated branch support.
348
            self.name)
0.200.412 by Jelmer Vernooij
Implement GitBranch.__repr__.
349
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
350
    def generate_revision_history(self, revid, old_revid=None):
0.200.1103 by Jelmer Vernooij
Support generate_revision_history(NULL_REVISION).
351
        if revid == NULL_REVISION:
352
            newhead = ZERO_SHA
353
        else:
354
            # FIXME: Check that old_revid is in the ancestry of revid
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
355
            newhead, self.mapping = self.repository.lookup_bzr_revision_id(revid)
0.200.1218 by Jelmer Vernooij
Support set_last_revision('null:').
356
            if self.mapping is None:
357
                raise AssertionError
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
358
        self._set_head(newhead)
359
0.200.1199 by Jelmer Vernooij
Support 'token' argument to Branch.lock_write.
360
    def lock_write(self, token=None):
361
        if token is not None:
362
            raise errors.TokenLockingNotSupported(self)
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
363
        if self._lock_mode:
364
            assert self._lock_mode == 'w'
365
            self._lock_count += 1
366
        else:
367
            self._lock_mode = 'w'
368
            self._lock_count = 1
369
        self.repository.lock_write()
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
370
        return GitWriteLock(self.unlock)
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
371
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
372
    def get_stacked_on_url(self):
373
        # Git doesn't do stacking (yet...)
0.200.631 by Jelmer Vernooij
Raise proper exception in Branch.get_stacked_on_url().
374
        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.
375
376
    def get_parent(self):
377
        """See Branch.get_parent()."""
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
378
        # 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.
379
        return None
380
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
381
    def set_parent(self, url):
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
382
        # FIXME: Set "origin" url in .git/config ?
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
383
        pass
384
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
385
    def lock_read(self):
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
386
        if self._lock_mode:
387
            assert self._lock_mode in ('r', 'w')
388
            self._lock_count += 1
389
        else:
390
            self._lock_mode = 'r'
391
            self._lock_count = 1
392
        self.repository.lock_read()
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
393
        return GitReadLock(self.unlock)
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
394
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
395
    def peek_lock_mode(self):
396
        return self._lock_mode
397
0.200.432 by Jelmer Vernooij
Support Branch.is_locked, required for loggerhead.
398
    def is_locked(self):
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
399
        return (self._lock_mode is not None)
0.200.432 by Jelmer Vernooij
Support Branch.is_locked, required for loggerhead.
400
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
401
    def unlock(self):
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
402
        """See Branch.unlock()."""
403
        self._lock_count -= 1
404
        if self._lock_count == 0:
405
            self._lock_mode = None
406
            self._clear_cached_state()
407
        self.repository.unlock()
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
408
409
    def get_physical_lock_status(self):
410
        return False
411
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
412
    @needs_read_lock
413
    def last_revision(self):
414
        # perhaps should escape this ?
0.200.57 by Jelmer Vernooij
Fix more tests.
415
        if self.head is None:
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
416
            return revision.NULL_REVISION
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
417
        return self.lookup_foreign_revision_id(self.head)
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
418
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
419
    def _basic_push(self, target, overwrite=False, stop_revision=None):
420
        return branch.InterBranch.get(self, target)._basic_push(
421
            overwrite, stop_revision)
422
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
423
    def lookup_foreign_revision_id(self, foreign_revid):
0.200.956 by Jelmer Vernooij
Add some more format tests.
424
        return self.repository.lookup_foreign_revision_id(foreign_revid,
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
425
            self.mapping)
426
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
427
    def lookup_bzr_revision_id(self, revid):
428
        return self.repository.lookup_bzr_revision_id(
429
            revid, mapping=self.mapping)
430
0.200.692 by Jelmer Vernooij
Refuse pulling into non-rich-root branches rather than erroring out with an AttributeError.
431
0.200.465 by Jelmer Vernooij
Use dulwich standard functionality for finding missing revisions.
432
class LocalGitBranch(GitBranch):
433
    """A local Git branch."""
434
0.200.1102 by Jelmer Vernooij
Fix creating of colocated branches in git repositories.
435
    def __init__(self, bzrdir, repository, ref, lockfiles, tagsdict=None):
436
        super(LocalGitBranch, self).__init__(bzrdir, repository, ref,
0.200.763 by Jelmer Vernooij
Provide proper colocated branch support.
437
              lockfiles, tagsdict)
0.200.918 by Jelmer Vernooij
Cope with 'self.ref is None' in a couple more places.
438
        refs = repository._git.get_refs()
0.200.1102 by Jelmer Vernooij
Fix creating of colocated branches in git repositories.
439
        if not (ref in refs.keys() or "HEAD" in refs.keys()):
0.200.763 by Jelmer Vernooij
Provide proper colocated branch support.
440
            raise errors.NotBranchError(self.base)
441
0.200.261 by Jelmer Vernooij
More formatting fixes.
442
    def create_checkout(self, to_location, revision_id=None, lightweight=False,
443
        accelerator_tree=None, hardlink=False):
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
444
        if lightweight:
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
445
            t = transport.get_transport(to_location)
446
            t.ensure_base()
0.200.1360 by Jelmer Vernooij
Support lighweight argument to _get_checkout_format.
447
            format = self._get_checkout_format(lightweight=True)
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
448
            checkout = format.initialize_on_transport(t)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
449
            from_branch = branch.BranchReferenceFormat().initialize(checkout,
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
450
                self)
451
            tree = checkout.create_workingtree(revision_id,
452
                from_branch=from_branch, hardlink=hardlink)
453
            return tree
454
        else:
455
            return self._create_heavyweight_checkout(to_location, revision_id,
0.257.1 by Jelmer Vernooij
use transport repo objects even for local access.
456
                hardlink)
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
457
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
458
    def _create_heavyweight_checkout(self, to_location, revision_id=None,
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
459
                                     hardlink=False):
460
        """Create a new heavyweight checkout of this branch.
461
462
        :param to_location: URL of location to create the new checkout in.
463
        :param revision_id: Revision that should be the tip of the checkout.
464
        :param hardlink: Whether to hardlink
465
        :return: WorkingTree object of checkout.
466
        """
0.200.513 by Jelmer Vernooij
Fix imports.
467
        checkout_branch = bzrdir.BzrDir.create_branch_convenience(
0.200.1360 by Jelmer Vernooij
Support lighweight argument to _get_checkout_format.
468
            to_location, force_new_tree=False,
469
            format=self._get_checkout_format(lightweight=False))
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
470
        checkout = checkout_branch.bzrdir
471
        checkout_branch.bind(self)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
472
        # 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.
473
        # branch tip correctly, and seed it with history.
474
        checkout_branch.pull(self, stop_revision=revision_id)
475
        return checkout.create_workingtree(revision_id, hardlink=hardlink)
476
0.200.57 by Jelmer Vernooij
Fix more tests.
477
    def _gen_revision_history(self):
0.200.58 by Jelmer Vernooij
Fix remaining tests.
478
        if self.head is None:
479
            return []
0.200.1279 by Jelmer Vernooij
Avoid using deprecated Repository.iter_reverse_revision_history.
480
        graph = self.repository.get_graph()
481
        ret = list(graph.iter_lefthand_ancestry(self.last_revision(),
482
            (revision.NULL_REVISION, )))
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
483
        ret.reverse()
0.200.57 by Jelmer Vernooij
Fix more tests.
484
        return ret
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
485
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
486
    def _get_head(self):
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
487
        try:
0.200.918 by Jelmer Vernooij
Cope with 'self.ref is None' in a couple more places.
488
            return self.repository._git.ref(self.ref or "HEAD")
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
489
        except KeyError:
490
            return None
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
491
0.200.1228 by Jelmer Vernooij
Provide Branch._read_last_revision_info.
492
    def _read_last_revision_info(self):
493
        last_revid = self.last_revision()
494
        graph = self.repository.get_graph()
495
        revno = graph.find_distance_to_null(last_revid,
496
            [(revision.NULL_REVISION, 0)])
497
        return revno, last_revid
498
499
    def set_last_revision_info(self, revno, revision_id):
500
        self.set_last_revision(revision_id)
501
        self._last_revision_info_cache = revno, revision_id
0.200.507 by Jelmer Vernooij
Implement set_last_revision{_info,}.
502
503
    def set_last_revision(self, revid):
0.200.1233 by Jelmer Vernooij
Implement Repository.iter_files_bytes.
504
        if not revid or not isinstance(revid, basestring):
505
            raise errors.InvalidRevisionId(revision_id=revid, branch=self)
0.200.1218 by Jelmer Vernooij
Support set_last_revision('null:').
506
        if revid == NULL_REVISION:
507
            newhead = ZERO_SHA
508
        else:
509
            (newhead, self.mapping) = self.repository.lookup_bzr_revision_id(revid)
510
            if self.mapping is None:
511
                raise AssertionError
512
        self._set_head(newhead)
0.200.507 by Jelmer Vernooij
Implement set_last_revision{_info,}.
513
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
514
    def _set_head(self, value):
515
        self._head = value
0.200.918 by Jelmer Vernooij
Cope with 'self.ref is None' in a couple more places.
516
        self.repository._git.refs[self.ref or "HEAD"] = self._head
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
517
        self._clear_cached_state()
518
519
    head = property(_get_head, _set_head)
520
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
521
    def get_config(self):
522
        return GitBranchConfig(self)
523
524
    def get_push_location(self):
525
        """See Branch.get_push_location."""
526
        push_loc = self.get_config().get_user_option('push_location')
527
        return push_loc
528
529
    def set_push_location(self, location):
530
        """See Branch.set_push_location."""
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
531
        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.
532
                                          store=config.STORE_LOCATION)
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
533
534
    def supports_tags(self):
0.200.82 by Jelmer Vernooij
Support listing tags.
535
        return True
0.200.956 by Jelmer Vernooij
Add some more format tests.
536
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
537
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
538
def _quick_lookup_revno(local_branch, remote_branch, revid):
539
    assert isinstance(revid, str), "was %r" % revid
540
    # Try in source branch first, it'll be faster
541
    try:
542
        return local_branch.revision_id_to_revno(revid)
543
    except errors.NoSuchRevision:
544
        graph = local_branch.repository.get_graph()
545
        try:
0.200.1323 by Jelmer Vernooij
Simplify push handling.
546
            return graph.find_distance_to_null(revid, [])
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
547
        except errors.GhostRevisionsHaveNoRevno:
548
            # FIXME: Check using graph.find_distance_to_null() ?
549
            return remote_branch.revision_id_to_revno(revid)
550
551
0.200.342 by Jelmer Vernooij
Report git sha during pull.
552
class GitBranchPullResult(branch.PullResult):
553
0.252.36 by Jelmer Vernooij
Fix pull.
554
    def __init__(self):
555
        super(GitBranchPullResult, self).__init__()
556
        self.new_git_head = None
557
        self._old_revno = None
558
        self._new_revno = None
559
0.200.342 by Jelmer Vernooij
Report git sha during pull.
560
    def report(self, to_file):
561
        if not is_quiet():
562
            if self.old_revid == self.new_revid:
563
                to_file.write('No revisions to pull.\n')
0.200.728 by Jelmer Vernooij
Fix pulling when all revisions are already in the repo.
564
            elif self.new_git_head is not None:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
565
                to_file.write('Now on revision %d (git sha: %s).\n' %
0.200.342 by Jelmer Vernooij
Report git sha during pull.
566
                        (self.new_revno, self.new_git_head))
0.200.728 by Jelmer Vernooij
Fix pulling when all revisions are already in the repo.
567
            else:
568
                to_file.write('Now on revision %d.\n' % (self.new_revno,))
0.200.342 by Jelmer Vernooij
Report git sha during pull.
569
        self._show_tag_conficts(to_file)
570
0.252.36 by Jelmer Vernooij
Fix pull.
571
    def _lookup_revno(self, revid):
0.200.1185 by Jelmer Vernooij
Some formatting fixes.
572
        return _quick_lookup_revno(self.target_branch, self.source_branch,
573
                revid)
0.252.36 by Jelmer Vernooij
Fix pull.
574
575
    def _get_old_revno(self):
576
        if self._old_revno is not None:
577
            return self._old_revno
578
        return self._lookup_revno(self.old_revid)
579
580
    def _set_old_revno(self, revno):
581
        self._old_revno = revno
582
583
    old_revno = property(_get_old_revno, _set_old_revno)
584
585
    def _get_new_revno(self):
586
        if self._new_revno is not None:
587
            return self._new_revno
588
        return self._lookup_revno(self.new_revid)
589
590
    def _set_new_revno(self, revno):
591
        self._new_revno = revno
0.200.956 by Jelmer Vernooij
Add some more format tests.
592
0.252.36 by Jelmer Vernooij
Fix pull.
593
    new_revno = property(_get_new_revno, _set_new_revno)
594
0.200.342 by Jelmer Vernooij
Report git sha during pull.
595
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
596
class GitBranchPushResult(branch.BranchPushResult):
597
598
    def _lookup_revno(self, revid):
0.200.1185 by Jelmer Vernooij
Some formatting fixes.
599
        return _quick_lookup_revno(self.source_branch, self.target_branch,
600
            revid)
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
601
602
    @property
603
    def old_revno(self):
604
        return self._lookup_revno(self.old_revid)
605
606
    @property
607
    def new_revno(self):
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
608
        new_original_revno = getattr(self, "new_original_revno", None)
609
        if new_original_revno:
610
            return new_original_revno
611
        if getattr(self, "new_original_revid", None) is not None:
612
            return self._lookup_revno(self.new_original_revid)
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
613
        return self._lookup_revno(self.new_revid)
614
615
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
616
class InterFromGitBranch(branch.GenericInterBranch):
0.200.261 by Jelmer Vernooij
More formatting fixes.
617
    """InterBranch implementation that pulls from Git into bzr."""
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
618
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
619
    @staticmethod
620
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
621
        try:
622
            default_format = branch.format_registry.get_default()
623
        except AttributeError:
624
            default_format = branch.BranchFormat._default_format
625
        return [
626
            (GitBranchFormat(), GitBranchFormat()),
627
            (GitBranchFormat(), default_format)]
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
628
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
629
    @classmethod
0.200.692 by Jelmer Vernooij
Refuse pulling into non-rich-root branches rather than erroring out with an AttributeError.
630
    def _get_interrepo(self, source, target):
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
631
        return _mod_repository.InterRepository.get(source.repository, target.repository)
0.200.692 by Jelmer Vernooij
Refuse pulling into non-rich-root branches rather than erroring out with an AttributeError.
632
633
    @classmethod
634
    def is_compatible(cls, source, target):
0.200.1222 by Jelmer Vernooij
Better checks in is_compatible methods.
635
        if not isinstance(source, GitBranch):
636
            return False
637
        if isinstance(target, GitBranch):
638
            # InterLocalGitRemoteGitBranch or InterToGitBranch should be used
639
            return False
640
        if getattr(cls._get_interrepo(source, target), "fetch_objects", None) is None:
641
            # fetch_objects is necessary for this to work
642
            return False
643
        return True
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
644
0.200.1305 by Jelmer Vernooij
Only actually fetch tags if "branch.fetch_tags" is set to true.
645
    def fetch(self, stop_revision=None, fetch_tags=None, limit=None):
0.200.1265 by Jelmer Vernooij
Support limit option to Branch.fetch.
646
        self.fetch_objects(stop_revision, fetch_tags=fetch_tags, limit=limit)
0.260.1 by Jelmer Vernooij
Fix fetch from remote during merge.
647
0.200.1265 by Jelmer Vernooij
Support limit option to Branch.fetch.
648
    def fetch_objects(self, stop_revision, fetch_tags, limit=None):
0.200.692 by Jelmer Vernooij
Refuse pulling into non-rich-root branches rather than erroring out with an AttributeError.
649
        interrepo = self._get_interrepo(self.source, self.target)
0.200.1305 by Jelmer Vernooij
Only actually fetch tags if "branch.fetch_tags" is set to true.
650
        if fetch_tags is None:
651
            c = self.source.get_config()
0.200.1306 by Jelmer Vernooij
Fix bzr 2.3 compatibility.
652
            fetch_tags = c.get_user_option_as_bool('branch.fetch_tags')
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
653
        def determine_wants(heads):
0.200.917 by Jelmer Vernooij
Cope with implicit branches during pull.
654
            if self.source.ref is not None and not self.source.ref in heads:
0.200.777 by Jelmer Vernooij
Fix colocated remote branches.
655
                raise NoSuchRef(self.source.ref, heads.keys())
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
656
657
            if stop_revision is None:
0.200.917 by Jelmer Vernooij
Cope with implicit branches during pull.
658
                if self.source.ref is not None:
659
                    head = heads[self.source.ref]
660
                else:
661
                    head = heads["HEAD"]
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
662
                self._last_revid = self.source.lookup_foreign_revision_id(head)
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
663
            else:
664
                self._last_revid = stop_revision
665
            real = interrepo.get_determine_wants_revids(
0.260.1 by Jelmer Vernooij
Fix fetch from remote during merge.
666
                [self._last_revid], include_tags=fetch_tags)
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
667
            return real(heads)
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
668
        pack_hint, head, refs = interrepo.fetch_objects(
0.200.1265 by Jelmer Vernooij
Support limit option to Branch.fetch.
669
            determine_wants, self.source.mapping, limit=limit)
0.252.45 by Jelmer Vernooij
Finish fetching roundtripped revisions back into bzr.
670
        if (pack_hint is not None and
671
            self.target.repository._format.pack_compresses):
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
672
            self.target.repository.pack(hint=pack_hint)
0.260.1 by Jelmer Vernooij
Fix fetch from remote during merge.
673
        return head, refs
674
0.200.1219 by Jelmer Vernooij
Remove InterBranch.update_revisions.
675
    def _update_revisions(self, stop_revision=None, overwrite=False):
0.200.1305 by Jelmer Vernooij
Only actually fetch tags if "branch.fetch_tags" is set to true.
676
        head, refs = self.fetch_objects(stop_revision, fetch_tags=None)
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
677
        if overwrite:
0.200.314 by Jelmer Vernooij
Support stop_revision.
678
            prev_last_revid = None
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
679
        else:
0.200.314 by Jelmer Vernooij
Support stop_revision.
680
            prev_last_revid = self.target.last_revision()
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
681
        self.target.generate_revision_history(self._last_revid,
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
682
            prev_last_revid, self.source)
0.200.1062 by Jelmer Vernooij
Pass remote refs along in _update_revisions.
683
        return head, refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
684
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
685
    def pull(self, overwrite=False, stop_revision=None,
686
             possible_transports=None, _hook_master=None, run_hooks=True,
0.200.1150 by Jelmer Vernooij
merge compatibility fixes for bzr 2.4, support for fetching tags.
687
             _override_hook_target=None, local=False):
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
688
        """See Branch.pull.
689
690
        :param _hook_master: Private parameter - set the branch to
691
            be supplied as the master to pull hooks.
692
        :param run_hooks: Private parameter - if false, this branch
693
            is being called because it's the master of the primary branch,
694
            so it should not run its hooks.
695
        :param _override_hook_target: Private parameter - set the branch to be
696
            supplied as the target_branch to pull hooks.
697
        """
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
698
        # This type of branch can't be bound.
699
        if local:
700
            raise errors.LocalRequiresBoundBranch()
0.200.342 by Jelmer Vernooij
Report git sha during pull.
701
        result = GitBranchPullResult()
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
702
        result.source_branch = self.source
703
        if _override_hook_target is None:
704
            result.target_branch = self.target
705
        else:
706
            result.target_branch = _override_hook_target
707
        self.source.lock_read()
708
        try:
0.200.1353 by Jelmer Vernooij
Run various hooks.
709
            self.target.lock_write()
710
            try:
711
                # We assume that during 'pull' the target repository is closer than
712
                # the source one.
713
                (result.old_revno, result.old_revid) = \
714
                    self.target.last_revision_info()
715
                result.new_git_head, remote_refs = self._update_revisions(
716
                    stop_revision, overwrite=overwrite)
717
                result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
718
                    overwrite)
719
                (result.new_revno, result.new_revid) = \
720
                    self.target.last_revision_info()
721
                if _hook_master:
722
                    result.master_branch = _hook_master
723
                    result.local_branch = result.target_branch
724
                else:
725
                    result.master_branch = result.target_branch
726
                    result.local_branch = None
727
                if run_hooks:
728
                    for hook in branch.Branch.hooks['post_pull']:
729
                        hook(result)
730
            finally:
731
                self.target.unlock()
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
732
        finally:
733
            self.source.unlock()
734
        return result
735
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
736
    def _basic_push(self, overwrite=False, stop_revision=None):
737
        result = branch.BranchPushResult()
738
        result.source_branch = self.source
739
        result.target_branch = self.target
740
        result.old_revno, result.old_revid = self.target.last_revision_info()
0.200.1219 by Jelmer Vernooij
Remove InterBranch.update_revisions.
741
        result.new_git_head, remote_refs = self._update_revisions(
742
            stop_revision, overwrite=overwrite)
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
743
        result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
744
            overwrite)
745
        result.new_revno, result.new_revid = self.target.last_revision_info()
746
        return result
747
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
748
0.200.512 by Jelmer Vernooij
Support pushing git->git.
749
class InterGitBranch(branch.GenericInterBranch):
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
750
    """InterBranch implementation that pulls between Git branches."""
751
0.200.512 by Jelmer Vernooij
Support pushing git->git.
752
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
753
class InterLocalGitRemoteGitBranch(InterGitBranch):
0.200.512 by Jelmer Vernooij
Support pushing git->git.
754
    """InterBranch that copies from a local to a remote git branch."""
755
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
756
    @staticmethod
757
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
758
        # FIXME
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
759
        return []
760
0.200.512 by Jelmer Vernooij
Support pushing git->git.
761
    @classmethod
762
    def is_compatible(self, source, target):
763
        from bzrlib.plugins.git.remote import RemoteGitBranch
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
764
        return (isinstance(source, LocalGitBranch) and
0.200.512 by Jelmer Vernooij
Support pushing git->git.
765
                isinstance(target, RemoteGitBranch))
766
767
    def _basic_push(self, overwrite=False, stop_revision=None):
768
        result = GitBranchPushResult()
769
        result.source_branch = self.source
770
        result.target_branch = self.target
771
        if stop_revision is None:
772
            stop_revision = self.source.last_revision()
773
        # FIXME: Check for diverged branches
774
        def get_changed_refs(old_refs):
0.200.1300 by Jelmer Vernooij
Fix formatting.
775
            old_ref = old_refs.get(self.target.ref, ZERO_SHA)
776
            result.old_revid = self.target.lookup_foreign_revision_id(old_ref)
0.200.822 by Jelmer Vernooij
Fix indication of number of revisions pushed in dpush.
777
            refs = { self.target.ref: self.source.repository.lookup_bzr_revision_id(stop_revision)[0] }
0.200.512 by Jelmer Vernooij
Support pushing git->git.
778
            result.new_revid = stop_revision
779
            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.
780
                refs[tag_name_to_ref(name)] = sha
0.200.512 by Jelmer Vernooij
Support pushing git->git.
781
            return refs
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
782
        self.target.repository.send_pack(get_changed_refs,
0.200.726 by Jelmer Vernooij
Factor out conversion of branch names to refs.
783
            self.source.repository._git.object_store.generate_pack_contents)
0.200.512 by Jelmer Vernooij
Support pushing git->git.
784
        return result
785
786
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
787
class InterGitLocalGitBranch(InterGitBranch):
0.200.512 by Jelmer Vernooij
Support pushing git->git.
788
    """InterBranch that copies from a remote to a local git branch."""
789
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
790
    @staticmethod
791
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
792
        # FIXME
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
793
        return []
794
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
795
    @classmethod
796
    def is_compatible(self, source, target):
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
797
        return (isinstance(source, GitBranch) and
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
798
                isinstance(target, LocalGitBranch))
799
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
800
    def _basic_push(self, overwrite=False, stop_revision=None):
0.200.1325 by Jelmer Vernooij
More test fixes.
801
        result = GitBranchPushResult()
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
802
        result.source_branch = self.source
803
        result.target_branch = self.target
804
        result.old_revid = self.target.last_revision()
805
        refs, stop_revision = self.update_refs(stop_revision)
806
        self.target.generate_revision_history(stop_revision, result.old_revid)
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
807
        result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
808
            source_refs=refs, overwrite=overwrite)
0.200.505 by Jelmer Vernooij
Remove duplicate code.
809
        result.new_revid = self.target.last_revision()
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
810
        return result
811
812
    def update_refs(self, stop_revision=None):
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
813
        interrepo = _mod_repository.InterRepository.get(self.source.repository,
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
814
            self.target.repository)
815
        if stop_revision is None:
0.200.940 by Jelmer Vernooij
Avoid confusion between different fetch functions with different semantics.
816
            refs = interrepo.fetch(branches=["HEAD"])
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
817
            stop_revision = self.target.lookup_foreign_revision_id(refs["HEAD"])
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
818
        else:
0.200.940 by Jelmer Vernooij
Avoid confusion between different fetch functions with different semantics.
819
            refs = interrepo.fetch(revision_id=stop_revision)
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
820
        return refs, stop_revision
821
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
822
    def pull(self, stop_revision=None, overwrite=False,
0.200.732 by Jelmer Vernooij
Support run_hooks argument to InterGitRemoteLocalBranch.pull().
823
        possible_transports=None, run_hooks=True,local=False):
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
824
        # This type of branch can't be bound.
825
        if local:
826
            raise errors.LocalRequiresBoundBranch()
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
827
        result = GitPullResult()
828
        result.source_branch = self.source
829
        result.target_branch = self.target
0.200.1353 by Jelmer Vernooij
Run various hooks.
830
        self.source.lock_read()
831
        try:
832
            self.target.lock_write()
833
            try:
834
                result.old_revid = self.target.last_revision()
835
                refs, stop_revision = self.update_refs(stop_revision)
836
                self.target.generate_revision_history(stop_revision, result.old_revid)
837
                result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
838
                    overwrite=overwrite, source_refs=refs)
839
                result.new_revid = self.target.last_revision()
840
                result.local_branch = None
841
                result.master_branch = result.target_branch
842
                if run_hooks:
843
                    for hook in branch.Branch.hooks['post_pull']:
844
                        hook(result)
845
            finally:
846
                self.target.unlock()
847
        finally:
848
            self.source.unlock()
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
849
        return result
850
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
851
0.200.960 by Jelmer Vernooij
Use GenericInterBranch.
852
class InterToGitBranch(branch.GenericInterBranch):
0.200.1185 by Jelmer Vernooij
Some formatting fixes.
853
    """InterBranch implementation that pulls into a Git branch."""
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
854
0.200.939 by Jelmer Vernooij
Use InterRepo directly.
855
    def __init__(self, source, target):
856
        super(InterToGitBranch, self).__init__(source, target)
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
857
        self.interrepo = _mod_repository.InterRepository.get(source.repository,
0.200.939 by Jelmer Vernooij
Use InterRepo directly.
858
                                           target.repository)
859
0.200.631 by Jelmer Vernooij
Raise proper exception in Branch.get_stacked_on_url().
860
    @staticmethod
861
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
862
        try:
863
            default_format = branch.format_registry.get_default()
864
        except AttributeError:
865
            default_format = branch.BranchFormat._default_format
866
        return [(default_format, GitBranchFormat())]
0.200.631 by Jelmer Vernooij
Raise proper exception in Branch.get_stacked_on_url().
867
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
868
    @classmethod
869
    def is_compatible(self, source, target):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
870
        return (not isinstance(source, GitBranch) and
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
871
                isinstance(target, GitBranch))
872
0.252.38 by Jelmer Vernooij
Minor cleanups.
873
    def _get_new_refs(self, stop_revision=None):
874
        if stop_revision is None:
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
875
            (stop_revno, stop_revision) = self.source.last_revision_info()
0.263.1 by Jelmer Vernooij
Fix dpush for certain branches.
876
        else:
877
            stop_revno = self.source.revision_id_to_revno(stop_revision)
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
878
        assert type(stop_revision) is str
0.200.916 by Jelmer Vernooij
Set refs/heads/master if no ref is set yet.
879
        main_ref = self.target.ref or "refs/heads/master"
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
880
        refs = { main_ref: (None, stop_revision) }
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
881
        for name, revid in self.source.tags.get_tag_dict().iteritems():
882
            if self.source.repository.has_revision(revid):
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
883
                refs[tag_name_to_ref(name)] = (None, revid)
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
884
        return refs, main_ref, (stop_revno, stop_revision)
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
885
0.252.36 by Jelmer Vernooij
Fix pull.
886
    def pull(self, overwrite=False, stop_revision=None, local=False,
0.200.1131 by Jelmer Vernooij
Accept run_hooks argument to InterToGitBranch.pull().
887
             possible_transports=None, run_hooks=True):
0.252.36 by Jelmer Vernooij
Fix pull.
888
        result = GitBranchPullResult()
889
        result.source_branch = self.source
890
        result.target_branch = self.target
0.200.1353 by Jelmer Vernooij
Run various hooks.
891
        self.source.lock_read()
0.200.1156 by Jelmer Vernooij
Disable push.
892
        try:
0.200.1353 by Jelmer Vernooij
Run various hooks.
893
            self.target.lock_write()
894
            try:
895
                new_refs, main_ref, stop_revinfo = self._get_new_refs(stop_revision)
896
                def update_refs(old_refs):
897
                    # FIXME: Check for diverged branches
898
                    return new_refs
899
                try:
900
                    result.revidmap, old_refs, new_refs = self.interrepo.fetch_refs(
901
                        update_refs, lossy=False)
902
                except NoPushSupport:
903
                    raise errors.NoRoundtrippingSupport(self.source, self.target)
904
                (result.old_revid, old_sha1) = old_refs.get(main_ref, (ZERO_SHA, NULL_REVISION))
905
                if result.old_revid is None:
906
                    result.old_revid = self.target.lookup_foreign_revision_id(old_sha1)
907
                result.new_revid = new_refs[main_ref][1]
908
                result.local_branch = None
909
                result.master_branch = self.target
910
                if run_hooks:
911
                    for hook in branch.Branch.hooks['post_pull']:
912
                        hook(result)
913
            finally:
914
                self.target.unlock()
915
        finally:
916
            self.source.unlock()
0.252.36 by Jelmer Vernooij
Fix pull.
917
        return result
918
0.200.1260 by Jelmer Vernooij
Cope with new lossy argument.
919
    def push(self, overwrite=False, stop_revision=None, lossy=False,
0.200.472 by Jelmer Vernooij
Fix printing error when user attempts to push into git.
920
             _override_hook_source_branch=None):
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
921
        result = GitBranchPushResult()
922
        result.source_branch = self.source
923
        result.target_branch = self.target
0.200.1356 by Jelmer Vernooij
Fix result properties for hook.
924
        result.local_branch = None
925
        result.master_branch = result.target_branch
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
926
        new_refs, main_ref, stop_revinfo = self._get_new_refs(stop_revision)
0.200.941 by Jelmer Vernooij
Pass update_refs argument to fetch_refs.
927
        def update_refs(old_refs):
0.200.945 by Jelmer Vernooij
Move fixmes
928
            # FIXME: Check for diverged branches
0.200.1323 by Jelmer Vernooij
Simplify push handling.
929
            return new_refs
930
        try:
931
            result.revidmap, old_refs, new_refs = self.interrepo.fetch_refs(
932
                update_refs, lossy=lossy)
933
        except NoPushSupport:
934
            raise errors.NoRoundtrippingSupport(self.source, self.target)
0.200.1035 by Jelmer Vernooij
Cope with tuples in refs dictionary.
935
        (result.old_revid, old_sha1) = old_refs.get(main_ref, (ZERO_SHA, NULL_REVISION))
936
        if result.old_revid is None:
937
            result.old_revid = self.target.lookup_foreign_revision_id(old_sha1)
0.200.1042 by Jelmer Vernooij
Fix pull into git branches.
938
        result.new_revid = new_refs[main_ref][1]
0.200.1260 by Jelmer Vernooij
Cope with new lossy argument.
939
        (result.new_original_revno, result.new_original_revid) = stop_revinfo
0.200.1353 by Jelmer Vernooij
Run various hooks.
940
        for hook in branch.Branch.hooks['post_push']:
941
            hook(result)
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
942
        return result
0.200.472 by Jelmer Vernooij
Fix printing error when user attempts to push into git.
943
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
944
    def lossy_push(self, stop_revision=None):
0.200.1261 by Jelmer Vernooij
add note about compatibility
945
        # For compatibility with bzr < 2.4
0.200.1260 by Jelmer Vernooij
Cope with new lossy argument.
946
        return self.push(lossy=True, stop_revision=stop_revision)
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
947
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
948
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
949
branch.InterBranch.register_optimiser(InterGitLocalGitBranch)
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
950
branch.InterBranch.register_optimiser(InterFromGitBranch)
951
branch.InterBranch.register_optimiser(InterToGitBranch)
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
952
branch.InterBranch.register_optimiser(InterLocalGitRemoteGitBranch)