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