/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.910 by Jelmer Vernooij
update copyright years
1
# Copyright (C) 2009-2010 Jelmer Vernooij <jelmer@samba.org>
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Push implementation that simply prints message saying push is not supported."""
18
0.200.1347 by Jelmer Vernooij
Provide search_missing_revisions.
19
from dulwich.objects import ZERO_SHA
20
from dulwich.walk import Walker
21
0.200.357 by Jelmer Vernooij
Move push code to push.py.
22
from bzrlib import (
0.200.598 by Jelmer Vernooij
Cope with ghosts.
23
    errors,
0.200.357 by Jelmer Vernooij
Move push code to push.py.
24
    ui,
25
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
26
from bzrlib.repository import (
27
    InterRepository,
28
    )
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
29
from bzrlib.revision import (
30
    NULL_REVISION,
31
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
32
33
from bzrlib.plugins.git.errors import (
34
    NoPushSupport,
35
    )
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
36
from bzrlib.plugins.git.object_store import (
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
37
    get_object_store,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
38
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
39
from bzrlib.plugins.git.repository import (
40
    GitRepository,
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
41
    LocalGitRepository,
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
42
    GitRepositoryFormat,
43
    )
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
44
from bzrlib.plugins.git.remote import (
45
    RemoteGitRepository,
46
    )
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
47
from bzrlib.plugins.git.unpeel_map import (
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
48
    UnpeelMap,
0.200.1061 by Jelmer Vernooij
Add support for using unpeel map.
49
    )
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
50
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
51
52
class MissingObjectsIterator(object):
53
    """Iterate over git objects that are missing from a target repository.
54
55
    """
56
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
57
    def __init__(self, store, source, pb=None):
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
58
        """Create a new missing objects iterator.
59
60
        """
61
        self.source = source
0.200.525 by Jelmer Vernooij
Simplify push a bit further, make dpush without rebase faster.
62
        self._object_store = store
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
63
        self._pending = []
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
64
        self.pb = pb
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
65
0.252.4 by Jelmer Vernooij
More work on roundtripping.
66
    def import_revisions(self, revids, roundtrip):
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
67
        """Import a set of revisions into this git repository.
68
69
        :param revids: Revision ids of revisions to import
70
        :param roundtrip: Whether to roundtrip bzr metadata
71
        """
0.200.369 by Jelmer Vernooij
Report on pack objects progress.
72
        for i, revid in enumerate(revids):
73
            if self.pb:
74
                self.pb.update("pushing revisions", i, len(revids))
0.252.4 by Jelmer Vernooij
More work on roundtripping.
75
            git_commit = self.import_revision(revid, roundtrip)
0.252.6 by Jelmer Vernooij
Roundtripping support for revision ids works.
76
            yield (revid, git_commit)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
77
0.252.4 by Jelmer Vernooij
More work on roundtripping.
78
    def import_revision(self, revid, roundtrip):
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
79
        """Import a revision into this Git repository.
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
80
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
81
        :param revid: Revision id of the revision
82
        :param roundtrip: Whether to roundtrip bzr metadata
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
83
        """
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
84
        tree = self._object_store.tree_cache.revision_tree(revid)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
85
        rev = self.source.get_revision(revid)
0.200.784 by Jelmer Vernooij
Use common object generation code in push.
86
        commit = None
0.252.4 by Jelmer Vernooij
More work on roundtripping.
87
        for path, obj, ie in self._object_store._revision_to_objects(rev, tree,
88
            roundtrip):
0.200.829 by Jelmer Vernooij
Cope with the fact that _type is gone in upstream dulwich.
89
            if obj.type_name == "commit":
0.200.784 by Jelmer Vernooij
Use common object generation code in push.
90
                commit = obj
0.200.786 by Jelmer Vernooij
Simplify push code.
91
            self._pending.append((obj, path))
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
92
        return commit.id
93
94
    def __len__(self):
95
        return len(self._pending)
96
97
    def __iter__(self):
0.200.786 by Jelmer Vernooij
Simplify push code.
98
        return iter(self._pending)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
99
100
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
101
class InterToGitRepository(InterRepository):
102
    """InterRepository that copies into a Git repository."""
103
104
    _matching_repo_format = GitRepositoryFormat()
105
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
106
    def __init__(self, source, target):
107
        super(InterToGitRepository, self).__init__(source, target)
108
        self.mapping = self.target.get_mapping()
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
109
        self.source_store = get_object_store(self.source, self.mapping)
0.200.435 by Jelmer Vernooij
Remember mapping per InterRepository.
110
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
111
    @staticmethod
112
    def _get_repo_format_to_test():
113
        return None
114
115
    def copy_content(self, revision_id=None, pb=None):
116
        """See InterRepository.copy_content."""
117
        self.fetch(revision_id, pb, find_ghosts=False)
118
0.200.1323 by Jelmer Vernooij
Simplify push handling.
119
    def fetch_refs(self, update_refs, lossy):
120
        """Fetch possibly roundtripped revisions into the target repository
121
        and update refs.
0.200.943 by Jelmer Vernooij
Add stubs.
122
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
123
        :param update_refs: Generate refs to fetch. Receives dictionary
124
            with old refs (git shas), returns dictionary of new names to
0.200.943 by Jelmer Vernooij
Add stubs.
125
            git shas.
0.200.1323 by Jelmer Vernooij
Simplify push handling.
126
        :param lossy: Whether to roundtrip
0.200.943 by Jelmer Vernooij
Add stubs.
127
        :return: old refs, new refs
128
        """
129
        raise NotImplementedError(self.fetch_refs)
130
0.200.1347 by Jelmer Vernooij
Provide search_missing_revisions.
131
    def search_missing_revision_ids(self,
132
            find_ghosts=True, revision_ids=None, if_present_ids=None,
133
            limit=None):
134
        git_shas = []
135
        todo = []
136
        if revision_ids:
137
            todo.extend(revision_ids)
138
        if if_present_ids:
139
            todo.extend(revision_ids)
140
        self.source_store.lock_read()
141
        try:
142
            for revid in revision_ids:
143
                if revid == NULL_REVISION:
144
                    continue
145
                git_sha = self.source_store._lookup_revision_sha1(revid)
146
                git_shas.append(git_sha)
147
            walker = Walker(self.source_store,
148
                include=git_shas, exclude=[sha for sha in self.target._git.get_refs().values() if sha != ZERO_SHA])
149
            missing_revids = set()
150
            for entry in walker:
0.200.1354 by Jelmer Vernooij
Fix re-looking up of revision ids.
151
                for (kind, type_data) in self.source_store.lookup_git_sha(entry.commit.id):
152
                    if kind == "commit":
153
                        missing_revids.add(type_data[0])
0.200.1347 by Jelmer Vernooij
Provide search_missing_revisions.
154
        finally:
155
            self.source_store.unlock()
156
        return self.source.revision_ids_to_search_result(missing_revids)
157
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
158
159
class InterToLocalGitRepository(InterToGitRepository):
0.200.966 by Jelmer Vernooij
Some more docstrings.
160
    """InterBranch implementation between a Bazaar and a Git repository."""
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
161
0.252.3 by Jelmer Vernooij
Refactor revision finding code.
162
    def __init__(self, source, target):
163
        super(InterToLocalGitRepository, self).__init__(source, target)
164
        self.target_store = self.target._git.object_store
0.252.6 by Jelmer Vernooij
Roundtripping support for revision ids works.
165
        self.target_refs = self.target._git.refs
0.252.3 by Jelmer Vernooij
Refactor revision finding code.
166
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
167
    def _revision_needs_fetching(self, sha_id, revid):
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
168
        if revid == NULL_REVISION:
169
            return False
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
170
        if sha_id is None:
171
            try:
172
                sha_id = self.source_store._lookup_revision_sha1(revid)
173
            except KeyError:
174
                return False
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
175
        try:
176
            return (sha_id not in self.target_store)
177
        except errors.NoSuchRevision:
178
            # Ghost, can't push
179
            return False
180
181
    def missing_revisions(self, stop_revisions):
0.200.966 by Jelmer Vernooij
Some more docstrings.
182
        """Find the revisions that are missing from the target repository.
183
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
184
        :param stop_revisions: Revisions to check for (tuples with
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
185
            Git SHA1, bzr revid)
0.200.966 by Jelmer Vernooij
Some more docstrings.
186
        :return: sequence of missing revisions, in topological order
0.200.968 by Jelmer Vernooij
Add more tests, simplify push code.
187
        :raise: NoSuchRevision if the stop_revisions are not present in
188
            the source
0.200.966 by Jelmer Vernooij
Some more docstrings.
189
        """
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
190
        revid_sha_map = {}
191
        stop_revids = []
192
        stop_sha1s = []
193
        for (sha1, revid) in stop_revisions:
194
            if sha1 is not None and revid is not None:
195
                revid_sha_map[revid] = sha1
196
            elif sha1 is not None:
197
                stop_sha1s.append(sha1)
198
            else:
199
                assert revid is not None
200
                stop_revids.append(revid)
0.200.357 by Jelmer Vernooij
Move push code to push.py.
201
        missing = []
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
202
        graph = self.source.get_graph()
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
203
        pb = ui.ui_factory.nested_progress_bar()
204
        try:
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
205
            for revid, _ in graph.iter_ancestry(stop_revids):
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
206
                assert type(revid) is str
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
207
                pb.update("determining revisions to fetch", len(missing))
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
208
                sha1 = revid_sha_map.get(revid)
209
                if self._revision_needs_fetching(sha1, revid):
0.200.371 by Jelmer Vernooij
Add progress bar when determining revisions to dpush
210
                    missing.append(revid)
211
        finally:
212
            pb.finished()
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
213
        for sha1 in stop_sha1s:
214
            try:
0.200.1167 by Jelmer Vernooij
Fix use of lookup_git_sha during push.
215
                for (kind, (revid, tree_sha, verifiers)) in self.source_store.lookup_git_sha(sha1):
216
                    missing.append(revid)
217
                    revid_sha_map[revid] = sha1
0.200.1036 by Jelmer Vernooij
More work on roundtrip push support.
218
            except KeyError:
219
                continue
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
220
        return graph.iter_topo_order(missing)
0.200.357 by Jelmer Vernooij
Move push code to push.py.
221
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
222
    def _get_target_bzr_refs(self):
223
        """Return a dictionary with references.
224
225
        :return: Dictionary with reference names as keys and tuples
226
            with Git SHA, Bazaar revid as values.
227
        """
228
        bzr_refs = {}
0.263.1 by Jelmer Vernooij
Fix dpush for certain branches.
229
        refs = {}
230
        for k in self.target._git.refs.allkeys():
231
            v = self.target._git.refs.read_ref(k)
0.200.1180 by Jelmer Vernooij
Some dpush fixes.
232
            try:
233
                for (kind, type_data) in self.source_store.lookup_git_sha(v):
0.200.1181 by Jelmer Vernooij
Simplify dfetch_refs for local git repositories.
234
                    if kind == "commit" and self.source.has_revision(type_data[0]):
0.200.1180 by Jelmer Vernooij
Some dpush fixes.
235
                        revid = type_data[0]
0.200.1181 by Jelmer Vernooij
Simplify dfetch_refs for local git repositories.
236
                        break
237
                else:
238
                    revid = None
0.200.1180 by Jelmer Vernooij
Some dpush fixes.
239
            except KeyError:
240
                revid = None
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
241
            bzr_refs[k] = (v, revid)
242
        return bzr_refs
243
0.200.1323 by Jelmer Vernooij
Simplify push handling.
244
    def fetch_refs(self, update_refs, lossy):
245
        self.source_store.lock_read()
246
        try:
247
            old_refs = self._get_target_bzr_refs()
248
            new_refs = update_refs(old_refs)
249
            revidmap = self.fetch_objects(new_refs.values(), roundtrip=not lossy)
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
250
            for name, (gitid, revid) in new_refs.iteritems():
0.200.1182 by Jelmer Vernooij
Fix local dpush.
251
                if gitid is None:
252
                    try:
0.200.1323 by Jelmer Vernooij
Simplify push handling.
253
                        gitid = revidmap[revid][0]
0.200.1182 by Jelmer Vernooij
Fix local dpush.
254
                    except KeyError:
255
                        gitid = self.source_store._lookup_revision_sha1(revid)
0.200.1323 by Jelmer Vernooij
Simplify push handling.
256
                assert len(gitid) == 40
0.200.1182 by Jelmer Vernooij
Fix local dpush.
257
                self.target_refs[name] = gitid
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
258
        finally:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
259
            self.source_store.unlock()
0.200.822 by Jelmer Vernooij
Fix indication of number of revisions pushed in dpush.
260
        return revidmap, old_refs, new_refs
0.200.428 by Jelmer Vernooij
use dfetch_refs, to prepare for dpush to remote repositories.
261
0.200.1323 by Jelmer Vernooij
Simplify push handling.
262
    def fetch_objects(self, revs, roundtrip):
263
        todo = list(self.missing_revisions(revs))
264
        revidmap = {}
265
        pb = ui.ui_factory.nested_progress_bar()
266
        try:
267
            object_generator = self._get_missing_objects_iterator(pb)
268
            for (old_revid, git_sha) in object_generator.import_revisions(
269
                todo, roundtrip=roundtrip):
270
                try:
271
                    self.mapping.revision_id_bzr_to_foreign(old_revid)
272
                except errors.InvalidRevisionId:
273
                    self.target_refs[self.mapping.revid_as_refname(old_revid)] = git_sha
274
                if not roundtrip:
275
                    new_revid = self.mapping.revision_id_foreign_to_bzr(git_sha)
276
                else:
277
                    new_revid = old_revid
278
                revidmap[old_revid] = (git_sha, new_revid)
279
            self.target_store.add_objects(object_generator)
280
            return revidmap
281
        finally:
282
            pb.finished()
283
0.200.947 by Jelmer Vernooij
Add convenience method for getting missing objects iterator.
284
    def _get_missing_objects_iterator(self, pb):
285
        return MissingObjectsIterator(self.source_store, self.source, pb)
286
0.200.524 by Jelmer Vernooij
Simplify dpushing multiple heads.
287
    def dfetch(self, stop_revisions):
0.200.357 by Jelmer Vernooij
Move push code to push.py.
288
        """Import the gist of the ancestry of a particular revision."""
289
0.252.4 by Jelmer Vernooij
More work on roundtripping.
290
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
0.200.1030 by Jelmer Vernooij
More work on supporting roundtripping push.
291
            fetch_spec=None, mapped_refs=None):
0.200.1156 by Jelmer Vernooij
Disable push.
292
        if not self.mapping.roundtripping:
293
            raise NoPushSupport()
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
294
        self.source_store.lock_read()
0.252.4 by Jelmer Vernooij
More work on roundtripping.
295
        try:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
296
            if mapped_refs is not None:
297
                stop_revisions = mapped_refs
298
            elif revision_id is not None:
299
                stop_revisions = [(None, revision_id)]
300
            elif fetch_spec is not None:
0.200.1365 by Jelmer Vernooij
Fix different fetch_spec types.
301
                recipe = fetch_spec.get_recipe()
302
                if recipe[0] in ("search", "proxy-search"):
303
                    stop_revisions = [(None, revid) for revid in recipe[1]]
304
                else:
305
                    raise AssertionError("Unsupported search result type %s" % recipe[0])
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
306
            else:
307
                stop_revisions = [(None, revid) for revid in self.source.all_revision_ids()]
0.200.1323 by Jelmer Vernooij
Simplify push handling.
308
            self.fetch_objects(stop_revisions, roundtrip=True)
0.252.4 by Jelmer Vernooij
More work on roundtripping.
309
        finally:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
310
            self.source_store.unlock()
0.252.4 by Jelmer Vernooij
More work on roundtripping.
311
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
312
    @staticmethod
313
    def is_compatible(source, target):
314
        """Be compatible with GitRepository."""
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
315
        return (not isinstance(source, GitRepository) and
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
316
                isinstance(target, LocalGitRepository))
317
318
319
class InterToRemoteGitRepository(InterToGitRepository):
320
0.200.1323 by Jelmer Vernooij
Simplify push handling.
321
    def fetch_refs(self, update_refs, lossy):
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
322
        """Import the gist of the ancestry of a particular revision."""
0.200.1323 by Jelmer Vernooij
Simplify push handling.
323
        if not lossy:
324
            raise NoPushSupport()
0.200.1065 by Jelmer Vernooij
Don't peel tags automatically when pushing back.
325
        unpeel_map = UnpeelMap.from_repository(self.source)
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
326
        revidmap = {}
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
327
        def determine_wants(old_refs):
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
328
            ret = {}
0.200.1052 by Jelmer Vernooij
Fix too many values to unpack error.
329
            self.old_refs = dict([(k, (v, None)) for (k, v) in old_refs.iteritems()])
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
330
            self.new_refs = update_refs(self.old_refs)
0.200.970 by Jelmer Vernooij
Fix dpush to remote locations.
331
            for name, (gitid, revid) in self.new_refs.iteritems():
332
                if gitid is None:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
333
                    git_sha = self.source_store._lookup_revision_sha1(revid)
334
                    ret[name] = unpeel_map.re_unpeel_tag(git_sha, old_refs.get(name))
0.200.970 by Jelmer Vernooij
Fix dpush to remote locations.
335
                else:
336
                    ret[name] = gitid
0.200.429 by Jelmer Vernooij
get remote dpush to a point where we now what to send.
337
            return ret
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
338
        self.source_store.lock_read()
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
339
        try:
0.200.460 by Jelmer Vernooij
Somewhat fix commit in git working trees.
340
            new_refs = self.target.send_pack(determine_wants,
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
341
                    self.source_store.generate_lossy_pack_contents)
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
342
        finally:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
343
            self.source_store.unlock()
0.200.1323 by Jelmer Vernooij
Simplify push handling.
344
        # FIXME: revidmap?
0.200.942 by Jelmer Vernooij
pass update_refs to dfetch_refs.
345
        return revidmap, self.old_refs, self.new_refs
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
346
347
    @staticmethod
348
    def is_compatible(source, target):
349
        """Be compatible with GitRepository."""
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
350
        return (not isinstance(source, GitRepository) and
0.200.425 by Jelmer Vernooij
Split out push to remote git repositories.
351
                isinstance(target, RemoteGitRepository))