/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.1613 by Jelmer Vernooij
Handle encoding better in working tree iter changes.
1
# Copyright (C) 2007,2012 Canonical Ltd
2
# Copyright (C) 2009-2012 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.1594 by Jelmer Vernooij
Use absolute_import everywhere.
20
from __future__ import absolute_import
21
0.200.1547 by Jelmer Vernooij
Support setting branch nicks.
22
from cStringIO import StringIO
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
23
from collections import defaultdict
24
0.200.261 by Jelmer Vernooij
More formatting fixes.
25
from dulwich.objects import (
0.200.1153 by Jelmer Vernooij
Import ZERO_SHA from dulwich.objects.
26
    ZERO_SHA,
0.200.261 by Jelmer Vernooij
More formatting fixes.
27
    )
0.200.1391 by Jelmer Vernooij
Warn on (and skip) invalid tags.
28
from dulwich.repo import check_ref_format
0.200.261 by Jelmer Vernooij
More formatting fixes.
29
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
30
from ... import (
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
31
    branch,
32
    config,
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
33
    controldir,
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
34
    errors,
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
35
    repository as _mod_repository,
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
36
    revision,
0.200.82 by Jelmer Vernooij
Support listing tags.
37
    tag,
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
38
    transport,
0.200.1414 by Jelmer Vernooij
Fix pulling into bound branches.
39
    urlutils,
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
40
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
41
from ...decorators import (
0.200.261 by Jelmer Vernooij
More formatting fixes.
42
    needs_read_lock,
43
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
44
from ...revision import (
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
45
    NULL_REVISION,
46
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
47
from ...trace import (
0.200.342 by Jelmer Vernooij
Report git sha during pull.
48
    is_quiet,
0.200.261 by Jelmer Vernooij
More formatting fixes.
49
    mutter,
0.200.1391 by Jelmer Vernooij
Warn on (and skip) invalid tags.
50
    warning,
0.200.261 by Jelmer Vernooij
More formatting fixes.
51
    )
52
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
53
from .config import (
0.200.386 by Jelmer Vernooij
Move config to a separate file, support BranchConfig.username().
54
    GitBranchConfig,
0.200.1472 by Jelmer Vernooij
Provide basic implementation of Branch.get_config_stack.
55
    GitBranchStack,
0.200.386 by Jelmer Vernooij
Move config to a separate file, support BranchConfig.username().
56
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
57
from .errors import (
0.200.472 by Jelmer Vernooij
Fix printing error when user attempts to push into git.
58
    NoPushSupport,
0.200.278 by Jelmer Vernooij
Update branch head appropriately during dpull.
59
    NoSuchRef,
60
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
61
from .refs import (
0.200.1061 by Jelmer Vernooij
Add support for using unpeel map.
62
    is_tag,
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
63
    ref_to_branch_name,
0.200.1061 by Jelmer Vernooij
Add support for using unpeel map.
64
    ref_to_tag_name,
0.200.875 by Jelmer Vernooij
Use new tag_name_to_ref function.
65
    tag_name_to_ref,
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
66
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
67
from .unpeel_map import (
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
68
    UnpeelMap,
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
69
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
70
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
71
from ...foreign import ForeignBranch
0.200.388 by Jelmer Vernooij
Support bzr 1.14 as well.
72
0.200.261 by Jelmer Vernooij
More formatting fixes.
73
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
74
class GitPullResult(branch.PullResult):
0.200.956 by Jelmer Vernooij
Add some more format tests.
75
    """Result of a pull from a Git branch."""
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
76
77
    def _lookup_revno(self, revid):
78
        assert isinstance(revid, str), "was %r" % revid
79
        # Try in source branch first, it'll be faster
0.200.1362 by Jelmer Vernooij
Add locking.
80
        self.target_branch.lock_read()
81
        try:
82
            return self.target_branch.revision_id_to_revno(revid)
83
        finally:
0.200.1367 by Jelmer Vernooij
Fix typo.
84
            self.target_branch.unlock()
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
85
86
    @property
87
    def old_revno(self):
88
        return self._lookup_revno(self.old_revid)
89
90
    @property
91
    def new_revno(self):
92
        return self._lookup_revno(self.new_revid)
93
94
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
95
class GitTags(tag.BasicTags):
96
    """Ref-based tag dictionary."""
0.200.82 by Jelmer Vernooij
Support listing tags.
97
0.200.89 by Jelmer Vernooij
Support sprouting branches.
98
    def __init__(self, branch):
99
        self.branch = branch
100
        self.repository = branch.repository
0.200.82 by Jelmer Vernooij
Support listing tags.
101
0.200.1487 by Jelmer Vernooij
Use peeling.
102
    def get_refs_container(self):
103
        raise NotImplementedError(self.get_refs_container)
0.200.1066 by Jelmer Vernooij
Add GitTags.get_refs.
104
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
105
    def _iter_tag_refs(self, refs):
0.200.1487 by Jelmer Vernooij
Use peeling.
106
        """Iterate over the tag refs.
107
108
        :param refs: Refs dictionary (name -> git sha1)
109
        :return: iterator over (name, peeled_sha1, unpeeled_sha1, bzr_revid)
110
        """
111
        for k, unpeeled in refs.as_dict().iteritems():
112
            try:
113
                tag_name = ref_to_tag_name(k)
114
            except (ValueError, UnicodeDecodeError):
115
                continue
116
            peeled = refs.get_peeled(k)
117
            if peeled is None:
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
118
                peeled = self.repository.controldir._git.object_store.peel_sha(unpeeled).id
0.200.1580 by Jelmer Vernooij
Add assertion.
119
            assert type(tag_name) is unicode
0.200.1487 by Jelmer Vernooij
Use peeling.
120
            yield (tag_name, peeled, unpeeled,
121
                   self.branch.lookup_foreign_revision_id(peeled))
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
122
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
123
    def _merge_to_remote_git(self, target_repo, new_refs, overwrite=False):
124
        updates = {}
125
        conflicts = []
126
        def get_changed_refs(old_refs):
127
            ret = dict(old_refs)
128
            for k, v in new_refs.iteritems():
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
129
                if not is_tag(k):
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
130
                    continue
131
                name = ref_to_tag_name(k)
132
                if old_refs.get(k) == v:
133
                    pass
134
                elif overwrite or not k in old_refs:
135
                    ret[k] = v
136
                    updates[name] = target_repo.lookup_foreign_revision_id(v)
137
                else:
138
                    conflicts.append((name, v, old_refs[k]))
139
            return ret
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
140
        target_repo.controldir.send_pack(get_changed_refs, lambda have, want: [])
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
141
        return updates, conflicts
142
143
    def _merge_to_local_git(self, target_repo, refs, overwrite=False):
144
        conflicts = []
145
        updates = {}
0.200.1489 by Jelmer Vernooij
More fixes to peel handling.
146
        for k, unpeeled in refs.as_dict().iteritems():
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
147
            if not is_tag(k):
148
                continue
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
149
            name = ref_to_tag_name(k)
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
150
            peeled = self.repository.controldir.get_peeled(k)
0.200.1489 by Jelmer Vernooij
More fixes to peel handling.
151
            if target_repo._git.refs.get(k) == unpeeled:
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
152
                pass
153
            elif overwrite or not k in target_repo._git.refs:
0.200.1460 by Jelmer Vernooij
Improve pulling into local git branches.
154
                target_repo._git.refs[k] = unpeeled or peeled
155
                updates[name] = target_repo.lookup_foreign_revision_id(peeled)
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
156
            else:
0.200.1493 by Jelmer Vernooij
Test fixes.
157
                conflicts.append((name, peeled, target_repo._git.refs[k]))
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
158
        return updates, conflicts
159
160
    def _merge_to_git(self, to_tags, refs, overwrite=False):
161
        target_repo = to_tags.repository
162
        if self.repository.has_same_location(target_repo):
163
            return {}, []
164
        if getattr(target_repo, "_git", None):
165
            return self._merge_to_local_git(target_repo, refs, overwrite)
166
        else:
167
            return self._merge_to_remote_git(target_repo, refs, overwrite)
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
168
169
    def _merge_to_non_git(self, to_tags, refs, overwrite=False):
170
        unpeeled_map = defaultdict(set)
171
        conflicts = []
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
172
        updates = {}
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
173
        result = dict(to_tags.get_tag_dict())
174
        for n, peeled, unpeeled, bzr_revid in self._iter_tag_refs(refs):
175
            if unpeeled is not None:
176
                unpeeled_map[peeled].add(unpeeled)
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
177
            if result.get(n) == bzr_revid:
178
                pass
179
            elif n not in result or overwrite:
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
180
                result[n] = bzr_revid
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
181
                updates[n] = bzr_revid
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
182
            else:
183
                conflicts.append((n, result[n], bzr_revid))
184
        to_tags._set_tag_dict(result)
185
        if len(unpeeled_map) > 0:
186
            map_file = UnpeelMap.from_repository(to_tags.branch.repository)
187
            map_file.update(unpeeled_map)
188
            map_file.save_in_repository(to_tags.branch.repository)
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
189
        return updates, conflicts
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
190
191
    def merge_to(self, to_tags, overwrite=False, ignore_master=False,
192
                 source_refs=None):
0.200.1113 by Jelmer Vernooij
Fix Tags.merge_to.
193
        """See Tags.merge_to."""
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
194
        if source_refs is None:
0.200.1487 by Jelmer Vernooij
Use peeling.
195
            source_refs = self.get_refs_container()
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
196
        if self == to_tags:
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
197
            return {}, []
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
198
        if isinstance(to_tags, GitTags):
199
            return self._merge_to_git(to_tags, source_refs,
200
                                      overwrite=overwrite)
201
        else:
202
            if ignore_master:
203
                master = None
204
            else:
205
                master = to_tags.branch.get_master_branch()
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
206
            updates, conflicts = self._merge_to_non_git(to_tags, source_refs,
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
207
                                              overwrite=overwrite)
208
            if master is not None:
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
209
                extra_updates, extra_conflicts = self.merge_to(
210
                    master.tags, overwrite=overwrite,
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
211
                                           source_refs=source_refs,
212
                                           ignore_master=ignore_master)
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
213
                updates.update(extra_updates)
214
                conflicts += extra_conflicts
215
            return updates, conflicts
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
216
217
    def get_tag_dict(self):
218
        ret = {}
0.200.1487 by Jelmer Vernooij
Use peeling.
219
        refs = self.get_refs_container()
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
220
        for (name, peeled, unpeeled, bzr_revid) in self._iter_tag_refs(refs):
221
            ret[name] = bzr_revid
222
        return ret
223
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
224
225
class LocalGitTagDict(GitTags):
226
    """Dictionary with tags in a local repository."""
227
228
    def __init__(self, branch):
229
        super(LocalGitTagDict, self).__init__(branch)
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
230
        self.refs = self.repository.controldir._git.refs
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
231
0.200.1487 by Jelmer Vernooij
Use peeling.
232
    def get_refs_container(self):
233
        return self.refs
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
234
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
235
    def _set_tag_dict(self, to_dict):
0.200.1487 by Jelmer Vernooij
Use peeling.
236
        extra = set(self.refs.allkeys())
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
237
        for k, revid in to_dict.iteritems():
0.200.875 by Jelmer Vernooij
Use new tag_name_to_ref function.
238
            name = tag_name_to_ref(k)
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
239
            if name in extra:
240
                extra.remove(name)
241
            self.set_tag(k, revid)
242
        for name in extra:
0.200.1061 by Jelmer Vernooij
Add support for using unpeel map.
243
            if is_tag(name):
0.200.711 by Jelmer Vernooij
Support merging tags to a local Git repository.
244
                del self.repository._git[name]
0.200.956 by Jelmer Vernooij
Add some more format tests.
245
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
246
    def set_tag(self, name, revid):
0.200.1369 by Jelmer Vernooij
Clarify that ghost tags are not supported.
247
        try:
248
            git_sha, mapping = self.branch.lookup_bzr_revision_id(revid)
249
        except errors.NoSuchRevision:
250
            raise errors.GhostTagsNotSupported(self)
251
        self.refs[tag_name_to_ref(name)] = git_sha
0.200.86 by Jelmer Vernooij
Clearer error when setting tags.
252
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
253
0.200.1078 by Jelmer Vernooij
Fix git-import from remote repositories.
254
class DictTagDict(tag.BasicTags):
0.239.1 by Jelmer Vernooij
Avoid re-connecting to fetch tags we already know.
255
256
    def __init__(self, branch, tags):
257
        super(DictTagDict, self).__init__(branch)
258
        self._tags = tags
259
260
    def get_tag_dict(self):
261
        return self._tags
262
263
0.200.1311 by Jelmer Vernooij
More work on colocated branch support.
264
class GitSymrefBranchFormat(branch.BranchFormat):
265
266
    def get_format_description(self):
267
        return 'Git Symbolic Reference Branch'
268
269
    def network_name(self):
270
        return "git"
271
272
    def get_reference(self, controldir, name=None):
273
        return controldir.get_branch_reference(name)
274
275
    def set_reference(self, controldir, name, target):
0.200.1559 by Jelmer Vernooij
Fix compatibility with bzr 2.5.
276
        return controldir.set_branch_reference(target, name)
0.200.1311 by Jelmer Vernooij
More work on colocated branch support.
277
278
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
279
class GitBranchFormat(branch.BranchFormat):
280
0.200.70 by Jelmer Vernooij
Implement GitBranchFormat.get_format_description.
281
    def get_format_description(self):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
282
        return 'Git Branch'
283
0.243.1 by Jelmer Vernooij
Use foreign branch testing infrastructure.
284
    def network_name(self):
285
        return "git"
286
0.200.82 by Jelmer Vernooij
Support listing tags.
287
    def supports_tags(self):
288
        return True
289
0.200.1105 by Jelmer Vernooij
Don't claim to support leaving locks.
290
    def supports_leaving_lock(self):
291
        return False
292
0.200.1369 by Jelmer Vernooij
Clarify that ghost tags are not supported.
293
    def supports_tags_referencing_ghosts(self):
294
        return False
295
296
    def tags_are_versioned(self):
297
        return False
298
0.200.1091 by Jelmer Vernooij
Provide _matchingbzrdir for testing.
299
    @property
300
    def _matchingbzrdir(self):
0.200.1644 by Jelmer Vernooij
More relative imports.
301
        from .dir import LocalGitControlDirFormat
0.200.1091 by Jelmer Vernooij
Provide _matchingbzrdir for testing.
302
        return LocalGitControlDirFormat()
303
0.243.1 by Jelmer Vernooij
Use foreign branch testing infrastructure.
304
    def get_foreign_tests_branch_factory(self):
0.200.1644 by Jelmer Vernooij
More relative imports.
305
        from .tests.test_branch import ForeignTestsBranchFactory
0.243.1 by Jelmer Vernooij
Use foreign branch testing infrastructure.
306
        return ForeignTestsBranchFactory()
307
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
308
    def make_tags(self, branch):
0.200.1487 by Jelmer Vernooij
Use peeling.
309
        try:
310
            return branch.tags
311
        except AttributeError:
312
            pass
0.200.1433 by Jelmer Vernooij
Fix fetching between git repositories.
313
        if getattr(branch.repository, "_git", None) is None:
0.200.1644 by Jelmer Vernooij
More relative imports.
314
            from .remote import RemoteGitTagDict
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
315
            return RemoteGitTagDict(branch)
0.200.261 by Jelmer Vernooij
More formatting fixes.
316
        else:
317
            return LocalGitTagDict(branch)
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
318
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
319
    def initialize(self, a_controldir, name=None, repository=None,
0.200.1378 by Jelmer Vernooij
Fix branch.
320
                   append_revisions_only=None):
0.200.1644 by Jelmer Vernooij
More relative imports.
321
        from .dir import LocalGitDir
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
322
        if not isinstance(a_controldir, LocalGitDir):
323
            raise errors.IncompatibleFormat(self, a_controldir._format)
324
        return a_controldir.create_branch(repository=repository, name=name,
0.200.1378 by Jelmer Vernooij
Fix branch.
325
            append_revisions_only=append_revisions_only)
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
326
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
327
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
328
class GitReadLock(object):
329
330
    def __init__(self, unlock):
331
        self.unlock = unlock
332
333
334
class GitWriteLock(object):
335
336
    def __init__(self, unlock):
0.200.1175 by Jelmer Vernooij
Provide GitWriteLock.branch_token.
337
        self.branch_token = None
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
338
        self.unlock = unlock
339
340
0.200.388 by Jelmer Vernooij
Support bzr 1.14 as well.
341
class GitBranch(ForeignBranch):
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
342
    """An adapter to git repositories for bzr Branch objects."""
343
0.200.1129 by Jelmer Vernooij
Implement GitBranch.control_transport.
344
    @property
345
    def control_transport(self):
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
346
        return self.controldir.control_transport
0.200.1129 by Jelmer Vernooij
Implement GitBranch.control_transport.
347
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
348
    def __init__(self, controldir, repository, ref):
349
        self.base = controldir.root_transport.base
0.200.82 by Jelmer Vernooij
Support listing tags.
350
        self.repository = repository
0.200.246 by Jelmer Vernooij
Cope with API changes in 1.13.
351
        self._format = GitBranchFormat()
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
352
        self.controldir = controldir
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
353
        self._lock_mode = None
354
        self._lock_count = 0
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
355
        super(GitBranch, self).__init__(repository.get_mapping())
0.200.770 by Jelmer Vernooij
Proper branch names.
356
        self.ref = ref
0.200.1361 by Jelmer Vernooij
Support branches where the ref can't be mapped back to a branch name.
357
        try:
358
            self.name = ref_to_branch_name(ref)
359
        except ValueError:
360
            self.name = None
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
361
        self._head = None
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
362
0.200.1360 by Jelmer Vernooij
Support lighweight argument to _get_checkout_format.
363
    def _get_checkout_format(self, lightweight=False):
0.239.8 by Jelmer Vernooij
Support checkouts.
364
        """Return the most suitable metadir for a checkout of this branch.
365
        Weaves are used if this branch's repository uses weaves.
366
        """
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
367
        return controldir.format_registry.make_controldir("default")
0.239.8 by Jelmer Vernooij
Support checkouts.
368
0.238.3 by Jelmer Vernooij
Remove svn references, prefer git send format when submitting changes against a git branch.
369
    def get_child_submit_format(self):
370
        """Return the preferred format of submissions to this branch."""
0.200.1584 by Jelmer Vernooij
Use config stacks in a few more places.
371
        ret = self.get_config_stack().get("child_submit_format")
0.238.3 by Jelmer Vernooij
Remove svn references, prefer git send format when submitting changes against a git branch.
372
        if ret is not None:
373
            return ret
374
        return "git"
375
0.200.1397 by Jelmer Vernooij
Fix use of get_config() for RemoteGitBranch.
376
    def get_config(self):
377
        return GitBranchConfig(self)
378
0.200.1472 by Jelmer Vernooij
Provide basic implementation of Branch.get_config_stack.
379
    def get_config_stack(self):
380
        return GitBranchStack(self)
381
0.200.293 by Jelmer Vernooij
Fix branch nicks.
382
    def _get_nick(self, local=False, possible_master_transports=None):
383
        """Find the nick name for this branch.
384
385
        :return: Branch nick
386
        """
0.200.1547 by Jelmer Vernooij
Support setting branch nicks.
387
        cs = self.repository._git.get_config_stack()
388
        try:
389
            return cs.get(("branch", self.name), "nick")
390
        except KeyError:
391
            pass
0.200.1534 by Jelmer Vernooij
Implement fetch between git branches, encode nicks.
392
        return self.name.encode('utf-8') or "HEAD"
0.200.293 by Jelmer Vernooij
Fix branch nicks.
393
0.200.331 by Jelmer Vernooij
Add stub for setting nick function.
394
    def _set_nick(self, nick):
0.200.1547 by Jelmer Vernooij
Support setting branch nicks.
395
        cf = self.repository._git.get_config()
396
        cf.set(("branch", self.name), "nick", nick)
397
        f = StringIO()
398
        cf.write_to_file(f)
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
399
        self.controldir.control_transport.put_bytes('config', f.getvalue())
0.200.331 by Jelmer Vernooij
Add stub for setting nick function.
400
401
    nick = property(_get_nick, _set_nick)
0.200.293 by Jelmer Vernooij
Fix branch nicks.
402
0.200.412 by Jelmer Vernooij
Implement GitBranch.__repr__.
403
    def __repr__(self):
0.200.770 by Jelmer Vernooij
Proper branch names.
404
        return "<%s(%r, %r)>" % (self.__class__.__name__, self.repository.base,
0.200.1311 by Jelmer Vernooij
More work on colocated branch support.
405
            self.name)
0.200.412 by Jelmer Vernooij
Implement GitBranch.__repr__.
406
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
407
    def generate_revision_history(self, revid, old_revid=None):
0.200.1103 by Jelmer Vernooij
Support generate_revision_history(NULL_REVISION).
408
        if revid == NULL_REVISION:
409
            newhead = ZERO_SHA
410
        else:
411
            # FIXME: Check that old_revid is in the ancestry of revid
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
412
            newhead, self.mapping = self.repository.lookup_bzr_revision_id(revid)
0.200.1218 by Jelmer Vernooij
Support set_last_revision('null:').
413
            if self.mapping is None:
414
                raise AssertionError
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
415
        self._set_head(newhead)
416
0.200.1199 by Jelmer Vernooij
Support 'token' argument to Branch.lock_write.
417
    def lock_write(self, token=None):
418
        if token is not None:
419
            raise errors.TokenLockingNotSupported(self)
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
420
        if self._lock_mode:
0.200.1369 by Jelmer Vernooij
Clarify that ghost tags are not supported.
421
            if self._lock_mode == 'r':
422
                raise errors.ReadOnlyError(self)
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
423
            self._lock_count += 1
424
        else:
425
            self._lock_mode = 'w'
426
            self._lock_count = 1
427
        self.repository.lock_write()
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
428
        return GitWriteLock(self.unlock)
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
429
0.200.1453 by Jelmer Vernooij
Provide Branch.leave_lock_in_place and Branch.dont_leave_lock_in_place.
430
    def leave_lock_in_place(self):
431
        raise NotImplementedError(self.leave_lock_in_place)
432
433
    def dont_leave_lock_in_place(self):
434
        raise NotImplementedError(self.dont_leave_lock_in_place)
435
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
436
    def get_stacked_on_url(self):
437
        # Git doesn't do stacking (yet...)
0.200.1660 by Jelmer Vernooij
Fix imports.
438
        raise branch.UnstackableBranchFormat(self._format, self.base)
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
439
440
    def get_parent(self):
441
        """See Branch.get_parent()."""
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
442
        # 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.
443
        return None
444
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
445
    def set_parent(self, url):
0.200.312 by Jelmer Vernooij
Add notes about parent locations.
446
        # FIXME: Set "origin" url in .git/config ?
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
447
        pass
448
0.200.1411 by Jelmer Vernooij
Fix control files.
449
    def break_lock(self):
450
        raise NotImplementedError(self.break_lock)
451
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
452
    def lock_read(self):
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
453
        if self._lock_mode:
454
            assert self._lock_mode in ('r', 'w')
455
            self._lock_count += 1
456
        else:
457
            self._lock_mode = 'r'
458
            self._lock_count = 1
459
        self.repository.lock_read()
0.200.911 by Jelmer Vernooij
Cope with locking changes in bzr.dev.
460
        return GitReadLock(self.unlock)
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
461
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
462
    def peek_lock_mode(self):
463
        return self._lock_mode
464
0.200.432 by Jelmer Vernooij
Support Branch.is_locked, required for loggerhead.
465
    def is_locked(self):
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
466
        return (self._lock_mode is not None)
0.200.432 by Jelmer Vernooij
Support Branch.is_locked, required for loggerhead.
467
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
468
    def unlock(self):
0.200.1250 by Jelmer Vernooij
Simplify lock handling.
469
        """See Branch.unlock()."""
470
        self._lock_count -= 1
471
        if self._lock_count == 0:
472
            self._lock_mode = None
473
            self._clear_cached_state()
474
        self.repository.unlock()
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
475
476
    def get_physical_lock_status(self):
477
        return False
478
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
479
    @needs_read_lock
480
    def last_revision(self):
481
        # perhaps should escape this ?
0.200.57 by Jelmer Vernooij
Fix more tests.
482
        if self.head is None:
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
483
            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.
484
        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.
485
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
486
    def _basic_push(self, target, overwrite=False, stop_revision=None):
487
        return branch.InterBranch.get(self, target)._basic_push(
488
            overwrite, stop_revision)
489
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
490
    def lookup_foreign_revision_id(self, foreign_revid):
0.200.956 by Jelmer Vernooij
Add some more format tests.
491
        return self.repository.lookup_foreign_revision_id(foreign_revid,
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
492
            self.mapping)
493
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
494
    def lookup_bzr_revision_id(self, revid):
495
        return self.repository.lookup_bzr_revision_id(
496
            revid, mapping=self.mapping)
497
0.200.692 by Jelmer Vernooij
Refuse pulling into non-rich-root branches rather than erroring out with an AttributeError.
498
0.200.465 by Jelmer Vernooij
Use dulwich standard functionality for finding missing revisions.
499
class LocalGitBranch(GitBranch):
500
    """A local Git branch."""
501
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
502
    def __init__(self, controldir, repository, ref):
503
        super(LocalGitBranch, self).__init__(controldir, repository, ref)
504
        refs = controldir.get_refs_container()
0.200.1487 by Jelmer Vernooij
Use peeling.
505
        if not (ref in refs or "HEAD" in refs):
0.200.763 by Jelmer Vernooij
Provide proper colocated branch support.
506
            raise errors.NotBranchError(self.base)
507
0.200.261 by Jelmer Vernooij
More formatting fixes.
508
    def create_checkout(self, to_location, revision_id=None, lightweight=False,
509
        accelerator_tree=None, hardlink=False):
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
510
        if lightweight:
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
511
            t = transport.get_transport(to_location)
512
            t.ensure_base()
0.200.1360 by Jelmer Vernooij
Support lighweight argument to _get_checkout_format.
513
            format = self._get_checkout_format(lightweight=True)
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
514
            checkout = format.initialize_on_transport(t)
0.200.1662 by Jelmer Vernooij
Fix import.
515
            from breezy.bzr.branch import BranchReferenceFormat
516
            from_branch = BranchReferenceFormat().initialize(checkout, self)
0.230.1 by Jelmer Vernooij
Support lightweight checkouts.
517
            tree = checkout.create_workingtree(revision_id,
518
                from_branch=from_branch, hardlink=hardlink)
519
            return tree
520
        else:
521
            return self._create_heavyweight_checkout(to_location, revision_id,
0.257.1 by Jelmer Vernooij
use transport repo objects even for local access.
522
                hardlink)
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
523
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
524
    def _create_heavyweight_checkout(self, to_location, revision_id=None,
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
525
                                     hardlink=False):
526
        """Create a new heavyweight checkout of this branch.
527
528
        :param to_location: URL of location to create the new checkout in.
529
        :param revision_id: Revision that should be the tip of the checkout.
530
        :param hardlink: Whether to hardlink
531
        :return: WorkingTree object of checkout.
532
        """
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
533
        checkout_branch = controldir.ControlDir.create_branch_convenience(
0.200.1360 by Jelmer Vernooij
Support lighweight argument to _get_checkout_format.
534
            to_location, force_new_tree=False,
535
            format=self._get_checkout_format(lightweight=False))
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
536
        checkout = checkout_branch.controldir
0.200.210 by Jelmer Vernooij
properly error out about not support lightweight checkouts.
537
        checkout_branch.bind(self)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
538
        # 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.
539
        # branch tip correctly, and seed it with history.
540
        checkout_branch.pull(self, stop_revision=revision_id)
541
        return checkout.create_workingtree(revision_id, hardlink=hardlink)
542
0.200.1493 by Jelmer Vernooij
Test fixes.
543
    def fetch(self, from_branch, last_revision=None, limit=None):
544
        return branch.InterBranch.get(from_branch, self).fetch(
545
            stop_revision=last_revision, limit=limit)
546
0.200.57 by Jelmer Vernooij
Fix more tests.
547
    def _gen_revision_history(self):
0.200.58 by Jelmer Vernooij
Fix remaining tests.
548
        if self.head is None:
549
            return []
0.200.1279 by Jelmer Vernooij
Avoid using deprecated Repository.iter_reverse_revision_history.
550
        graph = self.repository.get_graph()
551
        ret = list(graph.iter_lefthand_ancestry(self.last_revision(),
552
            (revision.NULL_REVISION, )))
0.200.59 by Jelmer Vernooij
Add more tests, fix revision history.
553
        ret.reverse()
0.200.57 by Jelmer Vernooij
Fix more tests.
554
        return ret
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
555
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
556
    def _get_head(self):
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
557
        try:
0.280.1 by Martin Pitt
Fix deprecated Repo.ref(), to make testsuite succeed again.
558
            return self.repository._git.refs[self.ref or "HEAD"]
0.200.480 by Jelmer Vernooij
Cope with API changes in Dulwich.
559
        except KeyError:
560
            return None
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
561
0.200.1228 by Jelmer Vernooij
Provide Branch._read_last_revision_info.
562
    def _read_last_revision_info(self):
563
        last_revid = self.last_revision()
564
        graph = self.repository.get_graph()
565
        revno = graph.find_distance_to_null(last_revid,
566
            [(revision.NULL_REVISION, 0)])
567
        return revno, last_revid
568
569
    def set_last_revision_info(self, revno, revision_id):
570
        self.set_last_revision(revision_id)
571
        self._last_revision_info_cache = revno, revision_id
0.200.507 by Jelmer Vernooij
Implement set_last_revision{_info,}.
572
573
    def set_last_revision(self, revid):
0.200.1233 by Jelmer Vernooij
Implement Repository.iter_files_bytes.
574
        if not revid or not isinstance(revid, basestring):
575
            raise errors.InvalidRevisionId(revision_id=revid, branch=self)
0.200.1218 by Jelmer Vernooij
Support set_last_revision('null:').
576
        if revid == NULL_REVISION:
577
            newhead = ZERO_SHA
578
        else:
579
            (newhead, self.mapping) = self.repository.lookup_bzr_revision_id(revid)
580
            if self.mapping is None:
581
                raise AssertionError
582
        self._set_head(newhead)
0.200.507 by Jelmer Vernooij
Implement set_last_revision{_info,}.
583
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
584
    def _set_head(self, value):
585
        self._head = value
0.200.918 by Jelmer Vernooij
Cope with 'self.ref is None' in a couple more places.
586
        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.
587
        self._clear_cached_state()
588
589
    head = property(_get_head, _set_head)
590
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
591
    def get_push_location(self):
592
        """See Branch.get_push_location."""
0.200.1584 by Jelmer Vernooij
Use config stacks in a few more places.
593
        push_loc = self.get_config_stack().get('push_location')
0.200.18 by John Arbash Meinel
Start splitting up the Git{Branch,Dir,Repository} into separate modules, etc.
594
        return push_loc
595
596
    def set_push_location(self, location):
597
        """See Branch.set_push_location."""
0.200.19 by John Arbash Meinel
More refactoring. Add some direct tests for GitModel.
598
        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.
599
                                          store=config.STORE_LOCATION)
0.200.43 by David Allouche
Ultra-experimental support for "bzr pull". No test. No sanity.
600
601
    def supports_tags(self):
0.200.82 by Jelmer Vernooij
Support listing tags.
602
        return True
0.200.956 by Jelmer Vernooij
Add some more format tests.
603
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
604
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
605
def _quick_lookup_revno(local_branch, remote_branch, revid):
606
    assert isinstance(revid, str), "was %r" % revid
607
    # Try in source branch first, it'll be faster
0.200.1362 by Jelmer Vernooij
Add locking.
608
    local_branch.lock_read()
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
609
    try:
610
        try:
0.200.1362 by Jelmer Vernooij
Add locking.
611
            return local_branch.revision_id_to_revno(revid)
612
        except errors.NoSuchRevision:
613
            graph = local_branch.repository.get_graph()
614
            try:
615
                return graph.find_distance_to_null(revid,
616
                    [(revision.NULL_REVISION, 0)])
617
            except errors.GhostRevisionsHaveNoRevno:
618
                # FIXME: Check using graph.find_distance_to_null() ?
619
                remote_branch.lock_read()
620
                try:
621
                    return remote_branch.revision_id_to_revno(revid)
622
                finally:
623
                    remote_branch.unlock()
624
    finally:
625
        local_branch.unlock()
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
626
627
0.200.342 by Jelmer Vernooij
Report git sha during pull.
628
class GitBranchPullResult(branch.PullResult):
629
0.252.36 by Jelmer Vernooij
Fix pull.
630
    def __init__(self):
631
        super(GitBranchPullResult, self).__init__()
632
        self.new_git_head = None
633
        self._old_revno = None
634
        self._new_revno = None
635
0.200.342 by Jelmer Vernooij
Report git sha during pull.
636
    def report(self, to_file):
637
        if not is_quiet():
638
            if self.old_revid == self.new_revid:
639
                to_file.write('No revisions to pull.\n')
0.200.728 by Jelmer Vernooij
Fix pulling when all revisions are already in the repo.
640
            elif self.new_git_head is not None:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
641
                to_file.write('Now on revision %d (git sha: %s).\n' %
0.200.342 by Jelmer Vernooij
Report git sha during pull.
642
                        (self.new_revno, self.new_git_head))
0.200.728 by Jelmer Vernooij
Fix pulling when all revisions are already in the repo.
643
            else:
644
                to_file.write('Now on revision %d.\n' % (self.new_revno,))
0.200.342 by Jelmer Vernooij
Report git sha during pull.
645
        self._show_tag_conficts(to_file)
646
0.252.36 by Jelmer Vernooij
Fix pull.
647
    def _lookup_revno(self, revid):
0.200.1185 by Jelmer Vernooij
Some formatting fixes.
648
        return _quick_lookup_revno(self.target_branch, self.source_branch,
0.200.1513 by Jelmer Vernooij
Cope with zero shas.
649
            revid)
0.252.36 by Jelmer Vernooij
Fix pull.
650
651
    def _get_old_revno(self):
652
        if self._old_revno is not None:
653
            return self._old_revno
654
        return self._lookup_revno(self.old_revid)
655
656
    def _set_old_revno(self, revno):
657
        self._old_revno = revno
658
659
    old_revno = property(_get_old_revno, _set_old_revno)
660
661
    def _get_new_revno(self):
662
        if self._new_revno is not None:
663
            return self._new_revno
664
        return self._lookup_revno(self.new_revid)
665
666
    def _set_new_revno(self, revno):
667
        self._new_revno = revno
0.200.956 by Jelmer Vernooij
Add some more format tests.
668
0.252.36 by Jelmer Vernooij
Fix pull.
669
    new_revno = property(_get_new_revno, _set_new_revno)
670
0.200.342 by Jelmer Vernooij
Report git sha during pull.
671
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
672
class GitBranchPushResult(branch.BranchPushResult):
673
674
    def _lookup_revno(self, revid):
0.200.1185 by Jelmer Vernooij
Some formatting fixes.
675
        return _quick_lookup_revno(self.source_branch, self.target_branch,
676
            revid)
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
677
678
    @property
679
    def old_revno(self):
680
        return self._lookup_revno(self.old_revid)
681
682
    @property
683
    def new_revno(self):
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
684
        new_original_revno = getattr(self, "new_original_revno", None)
685
        if new_original_revno:
686
            return new_original_revno
687
        if getattr(self, "new_original_revid", None) is not None:
688
            return self._lookup_revno(self.new_original_revid)
0.200.504 by Jelmer Vernooij
Lazily find revno's for git branches.
689
        return self._lookup_revno(self.new_revid)
690
691
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
692
class InterFromGitBranch(branch.GenericInterBranch):
0.200.261 by Jelmer Vernooij
More formatting fixes.
693
    """InterBranch implementation that pulls from Git into bzr."""
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
694
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
695
    @staticmethod
696
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
697
        try:
698
            default_format = branch.format_registry.get_default()
699
        except AttributeError:
700
            default_format = branch.BranchFormat._default_format
701
        return [
702
            (GitBranchFormat(), GitBranchFormat()),
703
            (GitBranchFormat(), default_format)]
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
704
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
705
    @classmethod
0.200.692 by Jelmer Vernooij
Refuse pulling into non-rich-root branches rather than erroring out with an AttributeError.
706
    def _get_interrepo(self, source, target):
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
707
        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.
708
709
    @classmethod
710
    def is_compatible(cls, source, target):
0.200.1222 by Jelmer Vernooij
Better checks in is_compatible methods.
711
        if not isinstance(source, GitBranch):
712
            return False
713
        if isinstance(target, GitBranch):
714
            # InterLocalGitRemoteGitBranch or InterToGitBranch should be used
715
            return False
716
        if getattr(cls._get_interrepo(source, target), "fetch_objects", None) is None:
717
            # fetch_objects is necessary for this to work
718
            return False
719
        return True
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
720
0.200.1305 by Jelmer Vernooij
Only actually fetch tags if "branch.fetch_tags" is set to true.
721
    def fetch(self, stop_revision=None, fetch_tags=None, limit=None):
0.200.1265 by Jelmer Vernooij
Support limit option to Branch.fetch.
722
        self.fetch_objects(stop_revision, fetch_tags=fetch_tags, limit=limit)
0.260.1 by Jelmer Vernooij
Fix fetch from remote during merge.
723
0.200.1265 by Jelmer Vernooij
Support limit option to Branch.fetch.
724
    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.
725
        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.
726
        if fetch_tags is None:
0.200.1584 by Jelmer Vernooij
Use config stacks in a few more places.
727
            c = self.source.get_config_stack()
728
            fetch_tags = c.get('branch.fetch_tags')
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
729
        def determine_wants(heads):
0.200.917 by Jelmer Vernooij
Cope with implicit branches during pull.
730
            if self.source.ref is not None and not self.source.ref in heads:
0.200.1386 by Jelmer Vernooij
Friendlier message if HEAD is not found.
731
                raise NoSuchRef(self.source.ref, self.source.user_url, heads.keys())
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
732
733
            if stop_revision is None:
0.200.917 by Jelmer Vernooij
Cope with implicit branches during pull.
734
                if self.source.ref is not None:
735
                    head = heads[self.source.ref]
736
                else:
737
                    head = heads["HEAD"]
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
738
                self._last_revid = self.source.lookup_foreign_revision_id(head)
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
739
            else:
740
                self._last_revid = stop_revision
741
            real = interrepo.get_determine_wants_revids(
0.260.1 by Jelmer Vernooij
Fix fetch from remote during merge.
742
                [self._last_revid], include_tags=fetch_tags)
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
743
            return real(heads)
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
744
        pack_hint, head, refs = interrepo.fetch_objects(
0.200.1265 by Jelmer Vernooij
Support limit option to Branch.fetch.
745
            determine_wants, self.source.mapping, limit=limit)
0.252.45 by Jelmer Vernooij
Finish fetching roundtripped revisions back into bzr.
746
        if (pack_hint is not None and
747
            self.target.repository._format.pack_compresses):
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
748
            self.target.repository.pack(hint=pack_hint)
0.260.1 by Jelmer Vernooij
Fix fetch from remote during merge.
749
        return head, refs
750
0.200.1219 by Jelmer Vernooij
Remove InterBranch.update_revisions.
751
    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.
752
        head, refs = self.fetch_objects(stop_revision, fetch_tags=None)
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
753
        if overwrite:
0.200.314 by Jelmer Vernooij
Support stop_revision.
754
            prev_last_revid = None
0.200.313 by Jelmer Vernooij
Support overwrite parameter.
755
        else:
0.200.314 by Jelmer Vernooij
Support stop_revision.
756
            prev_last_revid = self.target.last_revision()
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
757
        self.target.generate_revision_history(self._last_revid,
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
758
            prev_last_revid, self.source)
0.200.1062 by Jelmer Vernooij
Pass remote refs along in _update_revisions.
759
        return head, refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
760
0.200.1423 by Jelmer Vernooij
Fix space.
761
    def _basic_pull(self, stop_revision, overwrite, run_hooks,
0.200.1414 by Jelmer Vernooij
Fix pulling into bound branches.
762
              _override_hook_target, _hook_master):
0.200.342 by Jelmer Vernooij
Report git sha during pull.
763
        result = GitBranchPullResult()
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
764
        result.source_branch = self.source
765
        if _override_hook_target is None:
766
            result.target_branch = self.target
767
        else:
768
            result.target_branch = _override_hook_target
769
        self.source.lock_read()
770
        try:
0.200.1353 by Jelmer Vernooij
Run various hooks.
771
            self.target.lock_write()
772
            try:
773
                # We assume that during 'pull' the target repository is closer than
774
                # the source one.
775
                (result.old_revno, result.old_revid) = \
776
                    self.target.last_revision_info()
777
                result.new_git_head, remote_refs = self._update_revisions(
778
                    stop_revision, overwrite=overwrite)
0.200.1389 by Jelmer Vernooij
Some more tag fixes.
779
                tags_ret  = self.source.tags.merge_to(
0.200.1593 by Jelmer Vernooij
Fix dpushing from bound branch.
780
                        self.target.tags, overwrite, ignore_master=True)
0.200.1389 by Jelmer Vernooij
Some more tag fixes.
781
                if isinstance(tags_ret, tuple):
782
                    result.tag_updates, result.tag_conflicts = tags_ret
783
                else:
784
                    result.tag_conflicts = tags_ret
0.200.1353 by Jelmer Vernooij
Run various hooks.
785
                (result.new_revno, result.new_revid) = \
786
                    self.target.last_revision_info()
787
                if _hook_master:
788
                    result.master_branch = _hook_master
789
                    result.local_branch = result.target_branch
790
                else:
791
                    result.master_branch = result.target_branch
792
                    result.local_branch = None
793
                if run_hooks:
794
                    for hook in branch.Branch.hooks['post_pull']:
795
                        hook(result)
0.200.1417 by Jelmer Vernooij
Return pull result
796
                return result
0.200.1353 by Jelmer Vernooij
Run various hooks.
797
            finally:
798
                self.target.unlock()
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
799
        finally:
800
            self.source.unlock()
0.200.1414 by Jelmer Vernooij
Fix pulling into bound branches.
801
802
    def pull(self, overwrite=False, stop_revision=None,
803
             possible_transports=None, _hook_master=None, run_hooks=True,
804
             _override_hook_target=None, local=False):
805
        """See Branch.pull.
806
807
        :param _hook_master: Private parameter - set the branch to
808
            be supplied as the master to pull hooks.
809
        :param run_hooks: Private parameter - if false, this branch
810
            is being called because it's the master of the primary branch,
811
            so it should not run its hooks.
812
        :param _override_hook_target: Private parameter - set the branch to be
813
            supplied as the target_branch to pull hooks.
814
        """
815
        # This type of branch can't be bound.
816
        bound_location = self.target.get_bound_location()
817
        if local and not bound_location:
818
            raise errors.LocalRequiresBoundBranch()
819
        master_branch = None
820
        source_is_master = False
821
        self.source.lock_read()
822
        if bound_location:
823
            # bound_location comes from a config file, some care has to be
824
            # taken to relate it to source.user_url
825
            normalized = urlutils.normalize_url(bound_location)
826
            try:
827
                relpath = self.source.user_transport.relpath(normalized)
828
                source_is_master = (relpath == '')
0.200.1660 by Jelmer Vernooij
Fix imports.
829
            except (errors.PathNotChild, urlutils.InvalidURL):
0.200.1414 by Jelmer Vernooij
Fix pulling into bound branches.
830
                source_is_master = False
831
        if not local and bound_location and not source_is_master:
832
            # not pulling from master, so we need to update master.
833
            master_branch = self.target.get_master_branch(possible_transports)
834
            master_branch.lock_write()
835
        try:
836
            try:
837
                if master_branch:
838
                    # pull from source into master.
839
                    master_branch.pull(self.source, overwrite, stop_revision,
840
                        run_hooks=False)
841
                result = self._basic_pull(stop_revision, overwrite, run_hooks,
842
                    _override_hook_target, _hook_master=master_branch)
843
            finally:
844
                self.source.unlock()
845
        finally:
846
            if master_branch:
847
                master_branch.unlock()
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
848
        return result
849
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
850
    def _basic_push(self, overwrite=False, stop_revision=None):
851
        result = branch.BranchPushResult()
852
        result.source_branch = self.source
853
        result.target_branch = self.target
854
        result.old_revno, result.old_revid = self.target.last_revision_info()
0.200.1219 by Jelmer Vernooij
Remove InterBranch.update_revisions.
855
        result.new_git_head, remote_refs = self._update_revisions(
856
            stop_revision, overwrite=overwrite)
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
857
        tags_ret = self.source.tags.merge_to(self.target.tags,
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
858
            overwrite)
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
859
        if isinstance(tags_ret, tuple):
860
            (result.tag_updates, result.tag_conflicts) = tags_ret
861
        else:
862
            result.tag_conflicts = tags_ret
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
863
        result.new_revno, result.new_revid = self.target.last_revision_info()
864
        return result
865
0.200.338 by Jelmer Vernooij
Fix dpushing without changes necessary.
866
0.200.512 by Jelmer Vernooij
Support pushing git->git.
867
class InterGitBranch(branch.GenericInterBranch):
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
868
    """InterBranch implementation that pulls between Git branches."""
869
0.200.1493 by Jelmer Vernooij
Test fixes.
870
    def fetch(self, stop_revision=None, fetch_tags=None, limit=None):
871
        raise NotImplementedError(self.fetch)
872
0.200.512 by Jelmer Vernooij
Support pushing git->git.
873
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
874
class InterLocalGitRemoteGitBranch(InterGitBranch):
0.200.512 by Jelmer Vernooij
Support pushing git->git.
875
    """InterBranch that copies from a local to a remote git branch."""
876
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
877
    @staticmethod
878
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
879
        # FIXME
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
880
        return []
881
0.200.512 by Jelmer Vernooij
Support pushing git->git.
882
    @classmethod
883
    def is_compatible(self, source, target):
0.200.1644 by Jelmer Vernooij
More relative imports.
884
        from .remote import RemoteGitBranch
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
885
        return (isinstance(source, LocalGitBranch) and
0.200.512 by Jelmer Vernooij
Support pushing git->git.
886
                isinstance(target, RemoteGitBranch))
887
888
    def _basic_push(self, overwrite=False, stop_revision=None):
889
        result = GitBranchPushResult()
890
        result.source_branch = self.source
891
        result.target_branch = self.target
892
        if stop_revision is None:
893
            stop_revision = self.source.last_revision()
894
        # FIXME: Check for diverged branches
895
        def get_changed_refs(old_refs):
0.200.1300 by Jelmer Vernooij
Fix formatting.
896
            old_ref = old_refs.get(self.target.ref, ZERO_SHA)
897
            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.
898
            refs = { self.target.ref: self.source.repository.lookup_bzr_revision_id(stop_revision)[0] }
0.200.512 by Jelmer Vernooij
Support pushing git->git.
899
            result.new_revid = stop_revision
900
            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.
901
                refs[tag_name_to_ref(name)] = sha
0.200.512 by Jelmer Vernooij
Support pushing git->git.
902
            return refs
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
903
        self.target.repository.send_pack(get_changed_refs,
0.200.726 by Jelmer Vernooij
Factor out conversion of branch names to refs.
904
            self.source.repository._git.object_store.generate_pack_contents)
0.200.512 by Jelmer Vernooij
Support pushing git->git.
905
        return result
906
907
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
908
class InterGitLocalGitBranch(InterGitBranch):
0.200.512 by Jelmer Vernooij
Support pushing git->git.
909
    """InterBranch that copies from a remote to a local git branch."""
910
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
911
    @staticmethod
912
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
913
        # FIXME
0.200.996 by Jelmer Vernooij
Fix test run of InterBranches.
914
        return []
915
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
916
    @classmethod
917
    def is_compatible(self, source, target):
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
918
        return (isinstance(source, GitBranch) and
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
919
                isinstance(target, LocalGitBranch))
920
0.200.1534 by Jelmer Vernooij
Implement fetch between git branches, encode nicks.
921
    def fetch(self, stop_revision=None, fetch_tags=None, limit=None):
922
        interrepo = _mod_repository.InterRepository.get(self.source.repository,
923
            self.target.repository)
924
        if stop_revision is None:
925
            stop_revision = self.source.last_revision()
926
        determine_wants = interrepo.get_determine_wants_revids(
927
            [stop_revision], include_tags=fetch_tags)
928
        interrepo.fetch_objects(determine_wants, limit=limit)
929
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
930
    def _basic_push(self, overwrite=False, stop_revision=None):
0.200.1325 by Jelmer Vernooij
More test fixes.
931
        result = GitBranchPushResult()
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
932
        result.source_branch = self.source
933
        result.target_branch = self.target
934
        result.old_revid = self.target.last_revision()
935
        refs, stop_revision = self.update_refs(stop_revision)
936
        self.target.generate_revision_history(stop_revision, result.old_revid)
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
937
        tags_ret = self.source.tags.merge_to(self.target.tags,
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
938
            source_refs=refs, overwrite=overwrite)
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
939
        if isinstance(tags_ret, tuple):
940
            (result.tag_updates, result.tag_conflicts) = tags_ret
941
        else:
942
            result.tag_conflicts = tags_ret
0.200.505 by Jelmer Vernooij
Remove duplicate code.
943
        result.new_revid = self.target.last_revision()
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
944
        return result
945
946
    def update_refs(self, stop_revision=None):
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
947
        interrepo = _mod_repository.InterRepository.get(self.source.repository,
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
948
            self.target.repository)
949
        if stop_revision is None:
0.200.940 by Jelmer Vernooij
Avoid confusion between different fetch functions with different semantics.
950
            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.
951
            stop_revision = self.target.lookup_foreign_revision_id(refs["HEAD"])
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
952
        else:
0.200.940 by Jelmer Vernooij
Avoid confusion between different fetch functions with different semantics.
953
            refs = interrepo.fetch(revision_id=stop_revision)
0.200.501 by Jelmer Vernooij
Support push from git into bzr.
954
        return refs, stop_revision
955
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
956
    def pull(self, stop_revision=None, overwrite=False,
0.200.732 by Jelmer Vernooij
Support run_hooks argument to InterGitRemoteLocalBranch.pull().
957
        possible_transports=None, run_hooks=True,local=False):
0.200.446 by Jelmer Vernooij
Support new 'local' argument.
958
        # This type of branch can't be bound.
959
        if local:
960
            raise errors.LocalRequiresBoundBranch()
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
961
        result = GitPullResult()
962
        result.source_branch = self.source
963
        result.target_branch = self.target
0.200.1353 by Jelmer Vernooij
Run various hooks.
964
        self.source.lock_read()
965
        try:
966
            self.target.lock_write()
967
            try:
968
                result.old_revid = self.target.last_revision()
969
                refs, stop_revision = self.update_refs(stop_revision)
970
                self.target.generate_revision_history(stop_revision, result.old_revid)
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
971
                tags_ret = self.source.tags.merge_to(self.target.tags,
0.200.1353 by Jelmer Vernooij
Run various hooks.
972
                    overwrite=overwrite, source_refs=refs)
0.200.1402 by Jelmer Vernooij
Cope with tag changes in bzr.
973
                if isinstance(tags_ret, tuple):
974
                    (result.tag_updates, result.tag_conflicts) = tags_ret
975
                else:
976
                    result.tag_conflicts = tags_ret
0.200.1353 by Jelmer Vernooij
Run various hooks.
977
                result.new_revid = self.target.last_revision()
978
                result.local_branch = None
979
                result.master_branch = result.target_branch
980
                if run_hooks:
981
                    for hook in branch.Branch.hooks['post_pull']:
982
                        hook(result)
983
            finally:
984
                self.target.unlock()
985
        finally:
986
            self.source.unlock()
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
987
        return result
988
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
989
0.200.960 by Jelmer Vernooij
Use GenericInterBranch.
990
class InterToGitBranch(branch.GenericInterBranch):
0.200.1185 by Jelmer Vernooij
Some formatting fixes.
991
    """InterBranch implementation that pulls into a Git branch."""
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
992
0.200.939 by Jelmer Vernooij
Use InterRepo directly.
993
    def __init__(self, source, target):
994
        super(InterToGitBranch, self).__init__(source, target)
0.200.1097 by Jelmer Vernooij
Implement GitBranchFormat.initialize.
995
        self.interrepo = _mod_repository.InterRepository.get(source.repository,
0.200.939 by Jelmer Vernooij
Use InterRepo directly.
996
                                           target.repository)
997
0.200.631 by Jelmer Vernooij
Raise proper exception in Branch.get_stacked_on_url().
998
    @staticmethod
999
    def _get_branch_formats_to_test():
0.200.1100 by Jelmer Vernooij
Provide test combinations for InterBranch implementations.
1000
        try:
1001
            default_format = branch.format_registry.get_default()
1002
        except AttributeError:
1003
            default_format = branch.BranchFormat._default_format
1004
        return [(default_format, GitBranchFormat())]
0.200.631 by Jelmer Vernooij
Raise proper exception in Branch.get_stacked_on_url().
1005
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
1006
    @classmethod
1007
    def is_compatible(self, source, target):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
1008
        return (not isinstance(source, GitBranch) and
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
1009
                isinstance(target, GitBranch))
1010
0.200.1363 by Jelmer Vernooij
Only fetch tags if requested in config.
1011
    def _get_new_refs(self, stop_revision=None, fetch_tags=None):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
1012
        assert self.source.is_locked()
0.252.38 by Jelmer Vernooij
Minor cleanups.
1013
        if stop_revision is None:
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
1014
            (stop_revno, stop_revision) = self.source.last_revision_info()
0.263.1 by Jelmer Vernooij
Fix dpush for certain branches.
1015
        else:
1016
            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.
1017
        assert type(stop_revision) is str
0.200.916 by Jelmer Vernooij
Set refs/heads/master if no ref is set yet.
1018
        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.
1019
        refs = { main_ref: (None, stop_revision) }
0.200.1363 by Jelmer Vernooij
Only fetch tags if requested in config.
1020
        if fetch_tags is None:
0.200.1584 by Jelmer Vernooij
Use config stacks in a few more places.
1021
            c = self.source.get_config_stack()
1022
            fetch_tags = c.get('branch.fetch_tags')
0.200.1391 by Jelmer Vernooij
Warn on (and skip) invalid tags.
1023
        for name, revid in self.source.tags.get_tag_dict().iteritems():
1024
            if self.source.repository.has_revision(revid):
1025
                ref = tag_name_to_ref(name)
1026
                if not check_ref_format(ref):
1027
                    warning("skipping tag with invalid characters %s (%s)",
1028
                        name, ref)
1029
                    continue
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
1030
                if fetch_tags:
1031
                    # FIXME: Skip tags that are not in the ancestry
0.200.1391 by Jelmer Vernooij
Warn on (and skip) invalid tags.
1032
                    refs[ref] = (None, revid)
0.200.1048 by Jelmer Vernooij
Make lookup of revno's after push/pull as efficient as possible.
1033
        return refs, main_ref, (stop_revno, stop_revision)
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
1034
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1035
    def _update_refs(self, result, old_refs, new_refs, overwrite):
1036
        mutter("updating refs. old refs: %r, new refs: %r",
1037
               old_refs, new_refs)
1038
        result.tag_updates = {}
1039
        result.tag_conflicts = []
1040
        ret = dict(old_refs)
1041
        def ref_equals(refs, ref, git_sha, revid):
1042
            try:
1043
                value = refs[ref]
1044
            except KeyError:
1045
                return False
1046
            if (value[0] is not None and
1047
                git_sha is not None and
0.200.1479 by Jelmer Vernooij
Simplify branch ref handling.
1048
                value[0] == git_sha):
1049
                return True
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1050
            if (value[1] is not None and
1051
                revid is not None and
0.200.1479 by Jelmer Vernooij
Simplify branch ref handling.
1052
                value[1] == revid):
1053
                return True
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1054
            # FIXME: If one side only has the git sha available and the other only
1055
            # has the bzr revid, then this will cause us to show a tag as updated
0.200.1636 by Jelmer Vernooij
Some formatting fixes.
1056
            # that hasn't actually been updated.
0.200.1479 by Jelmer Vernooij
Simplify branch ref handling.
1057
            return False
0.200.1474 by Jelmer Vernooij
Cope with refs when pushing.
1058
        # FIXME: Check for diverged branches
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1059
        for ref, (git_sha, revid) in new_refs.iteritems():
0.200.1479 by Jelmer Vernooij
Simplify branch ref handling.
1060
            if ref_equals(ret, ref, git_sha, revid):
1061
                # Already up to date
1062
                if git_sha is None:
1063
                    git_sha = old_refs[ref][0]
1064
                if revid is None:
1065
                    revid = old_refs[ref][1]
1066
                ret[ref] = new_refs[ref] = (git_sha, revid)
1067
            elif ref not in ret or overwrite:
1068
                try:
1069
                    tag_name = ref_to_tag_name(ref)
1070
                except ValueError:
1071
                    pass
1072
                else:
1073
                    result.tag_updates[tag_name] = revid
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1074
                ret[ref] = (git_sha, revid)
1075
            else:
0.200.1474 by Jelmer Vernooij
Cope with refs when pushing.
1076
                # FIXME: Check diverged
1077
                diverged = False
1078
                if diverged:
1079
                    try:
1080
                        name = ref_to_tag_name(ref)
1081
                    except ValueError:
1082
                        pass
1083
                    else:
1084
                        result.tag_conflicts.append((name, revid, ret[name][1]))
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1085
                else:
0.200.1474 by Jelmer Vernooij
Cope with refs when pushing.
1086
                    ret[ref] = (git_sha, revid)
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1087
        return ret
1088
0.200.1493 by Jelmer Vernooij
Test fixes.
1089
    def fetch(self, stop_revision=None, fetch_tags=None, lossy=False, limit=None):
1090
        assert limit is None
1091
        if stop_revision is None:
1092
            stop_revision = self.source.last_revision()
1093
        ret = []
1094
        if fetch_tags:
1095
            for k, v in self.source.tags.get_tag_dict().iteritems():
1096
                ret.append((None, v))
1097
        ret.append((None, stop_revision))
0.200.1509 by Jelmer Vernooij
Properly raise exception when pulling from git into bzr without experimental mappings.
1098
        self.interrepo.fetch_objects(ret, lossy=lossy)
0.200.1493 by Jelmer Vernooij
Test fixes.
1099
0.252.36 by Jelmer Vernooij
Fix pull.
1100
    def pull(self, overwrite=False, stop_revision=None, local=False,
0.200.1131 by Jelmer Vernooij
Accept run_hooks argument to InterToGitBranch.pull().
1101
             possible_transports=None, run_hooks=True):
0.252.36 by Jelmer Vernooij
Fix pull.
1102
        result = GitBranchPullResult()
1103
        result.source_branch = self.source
1104
        result.target_branch = self.target
0.200.1353 by Jelmer Vernooij
Run various hooks.
1105
        self.source.lock_read()
0.200.1156 by Jelmer Vernooij
Disable push.
1106
        try:
0.200.1353 by Jelmer Vernooij
Run various hooks.
1107
            self.target.lock_write()
1108
            try:
0.200.1389 by Jelmer Vernooij
Some more tag fixes.
1109
                new_refs, main_ref, stop_revinfo = self._get_new_refs(
1110
                    stop_revision)
0.200.1353 by Jelmer Vernooij
Run various hooks.
1111
                def update_refs(old_refs):
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1112
                    return self._update_refs(result, old_refs, new_refs, overwrite)
0.200.1353 by Jelmer Vernooij
Run various hooks.
1113
                try:
1114
                    result.revidmap, old_refs, new_refs = self.interrepo.fetch_refs(
1115
                        update_refs, lossy=False)
1116
                except NoPushSupport:
1117
                    raise errors.NoRoundtrippingSupport(self.source, self.target)
0.200.1513 by Jelmer Vernooij
Cope with zero shas.
1118
                (old_sha1, result.old_revid) = old_refs.get(main_ref, (ZERO_SHA, NULL_REVISION))
0.200.1353 by Jelmer Vernooij
Run various hooks.
1119
                if result.old_revid is None:
1120
                    result.old_revid = self.target.lookup_foreign_revision_id(old_sha1)
1121
                result.new_revid = new_refs[main_ref][1]
1122
                result.local_branch = None
1123
                result.master_branch = self.target
1124
                if run_hooks:
1125
                    for hook in branch.Branch.hooks['post_pull']:
1126
                        hook(result)
1127
            finally:
1128
                self.target.unlock()
1129
        finally:
1130
            self.source.unlock()
0.252.36 by Jelmer Vernooij
Fix pull.
1131
        return result
1132
0.200.1260 by Jelmer Vernooij
Cope with new lossy argument.
1133
    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.
1134
             _override_hook_source_branch=None):
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
1135
        result = GitBranchPushResult()
1136
        result.source_branch = self.source
1137
        result.target_branch = self.target
0.200.1356 by Jelmer Vernooij
Fix result properties for hook.
1138
        result.local_branch = None
1139
        result.master_branch = result.target_branch
0.200.1391 by Jelmer Vernooij
Warn on (and skip) invalid tags.
1140
        self.source.lock_read()
0.200.1323 by Jelmer Vernooij
Simplify push handling.
1141
        try:
0.200.1391 by Jelmer Vernooij
Warn on (and skip) invalid tags.
1142
            new_refs, main_ref, stop_revinfo = self._get_new_refs(stop_revision)
1143
            def update_refs(old_refs):
0.200.1392 by Jelmer Vernooij
Preserve existing refs.
1144
                return self._update_refs(result, old_refs, new_refs, overwrite)
0.200.1391 by Jelmer Vernooij
Warn on (and skip) invalid tags.
1145
            try:
1146
                result.revidmap, old_refs, new_refs = self.interrepo.fetch_refs(
1147
                    update_refs, lossy=lossy)
1148
            except NoPushSupport:
1149
                raise errors.NoRoundtrippingSupport(self.source, self.target)
1150
            (old_sha1, result.old_revid) = old_refs.get(main_ref, (ZERO_SHA, NULL_REVISION))
1151
            if result.old_revid is None:
1152
                result.old_revid = self.target.lookup_foreign_revision_id(old_sha1)
1153
            result.new_revid = new_refs[main_ref][1]
1154
            (result.new_original_revno, result.new_original_revid) = stop_revinfo
1155
            for hook in branch.Branch.hooks['post_push']:
1156
                hook(result)
1157
        finally:
1158
            self.source.unlock()
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
1159
        return result
0.200.472 by Jelmer Vernooij
Fix printing error when user attempts to push into git.
1160
0.200.334 by Jelmer Vernooij
Support pulling from git to git.
1161
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
1162
branch.InterBranch.register_optimiser(InterGitLocalGitBranch)
0.200.468 by Jelmer Vernooij
Move dpush logic onto InterBranch.
1163
branch.InterBranch.register_optimiser(InterFromGitBranch)
1164
branch.InterBranch.register_optimiser(InterToGitBranch)
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
1165
branch.InterBranch.register_optimiser(InterLocalGitRemoteGitBranch)