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