/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
1
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
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
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
17
from cStringIO import StringIO
18
import dulwich as git
0.200.261 by Jelmer Vernooij
More formatting fixes.
19
from dulwich.client import (
20
    SimpleFetchGraphWalker,
21
    )
22
from dulwich.objects import (
23
    Commit,
24
    )
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
25
26
from bzrlib import (
27
    osutils,
0.200.261 by Jelmer Vernooij
More formatting fixes.
28
    trace,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
29
    ui,
30
    urlutils,
31
    )
32
from bzrlib.errors import (
33
    InvalidRevisionId,
34
    NoSuchRevision,
35
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
36
from bzrlib.inventory import (
37
    Inventory,
38
    )
39
from bzrlib.repository import (
40
    InterRepository,
41
    )
0.200.158 by Jelmer Vernooij
fetch works \o/
42
from bzrlib.tsort import topo_sort
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
43
0.200.261 by Jelmer Vernooij
More formatting fixes.
44
from bzrlib.plugins.git.converter import (
45
    GitObjectConverter,
46
    )
0.200.169 by Jelmer Vernooij
Fix branch cloning.
47
from bzrlib.plugins.git.repository import (
0.200.261 by Jelmer Vernooij
More formatting fixes.
48
    LocalGitRepository, 
49
    GitRepository, 
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
50
    GitRepositoryFormat,
0.200.261 by Jelmer Vernooij
More formatting fixes.
51
    )
52
from bzrlib.plugins.git.remote import (
53
    RemoteGitRepository,
54
    )
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
55
56
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
57
class BzrFetchGraphWalker(object):
0.200.196 by Jelmer Vernooij
Add simple tests and docstrings for GraphWalker.
58
    """GraphWalker implementation that uses a Bazaar repository."""
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
59
60
    def __init__(self, repository, mapping):
61
        self.repository = repository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
62
        self.mapping = mapping
63
        self.done = set()
64
        self.heads = set(repository.all_revision_ids())
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
65
        self.parents = {}
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
66
0.200.196 by Jelmer Vernooij
Add simple tests and docstrings for GraphWalker.
67
    def __iter__(self):
68
        return iter(self.next, None)
69
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
70
    def ack(self, sha):
71
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
72
        self.remove(revid)
73
74
    def remove(self, revid):
75
        self.done.add(revid)
0.200.177 by Jelmer Vernooij
Add git-import command.
76
        if revid in self.heads:
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
77
            self.heads.remove(revid)
78
        if revid in self.parents:
79
            for p in self.parents[revid]:
80
                self.remove(p)
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
81
82
    def next(self):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
83
        while self.heads:
84
            ret = self.heads.pop()
85
            ps = self.repository.get_parent_map([ret])[ret]
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
86
            self.parents[ret] = ps
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
87
            self.heads.update([p for p in ps if not p in self.done])
88
            try:
89
                self.done.add(ret)
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
90
                return self.mapping.revision_id_bzr_to_foreign(ret)[0]
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
91
            except InvalidRevisionId:
92
                pass
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
93
        return None
94
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
95
0.200.264 by Jelmer Vernooij
Add more tests.
96
def import_git_blob(texts, mapping, path, blob, inv, parent_invs, shagitmap,
0.200.261 by Jelmer Vernooij
More formatting fixes.
97
    executable):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
98
    """Import a git blob object into a bzr repository.
99
0.200.261 by Jelmer Vernooij
More formatting fixes.
100
    :param texts: VersionedFiles to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
101
    :param path: Path in the tree
102
    :param blob: A git blob
0.200.286 by Jelmer Vernooij
Prevent creating repeated directory texts.
103
    :return: Inventory entry
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
104
    """
105
    file_id = mapping.generate_file_id(path)
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
106
    ie = inv.add_path(path, "file", file_id)
0.200.158 by Jelmer Vernooij
fetch works \o/
107
    ie.text_size = len(blob.data)
108
    ie.text_sha1 = osutils.sha_string(blob.data)
0.200.159 by Jelmer Vernooij
Fix branch tests.
109
    ie.executable = executable
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
110
    # See if this is the same revision as one of the parents unchanged
111
    parent_keys = []
112
    for pinv in parent_invs:
0.200.285 by Jelmer Vernooij
Simplify blob import code.
113
        if not file_id in pinv:
114
            continue
115
        if pinv[file_id].text_sha1 == ie.text_sha1:
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
116
            ie.revision = pinv[file_id].revision
0.200.286 by Jelmer Vernooij
Prevent creating repeated directory texts.
117
            return ie
118
        parent_keys.append((file_id, pinv[file_id].revision))
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
119
    ie.revision = inv.revision_id
120
    assert file_id is not None
121
    assert ie.revision is not None
0.200.285 by Jelmer Vernooij
Simplify blob import code.
122
    texts.add_lines((file_id, ie.revision), parent_keys,
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
123
        osutils.split_lines(blob.data))
0.200.264 by Jelmer Vernooij
Add more tests.
124
    shagitmap.add_entry(blob.sha().hexdigest(), "blob",
0.200.261 by Jelmer Vernooij
More formatting fixes.
125
        (ie.file_id, ie.revision))
0.200.286 by Jelmer Vernooij
Prevent creating repeated directory texts.
126
    return ie
0.200.261 by Jelmer Vernooij
More formatting fixes.
127
128
0.200.264 by Jelmer Vernooij
Add more tests.
129
def import_git_tree(texts, mapping, path, tree, inv, parent_invs, shagitmap,
0.200.261 by Jelmer Vernooij
More formatting fixes.
130
    lookup_object):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
131
    """Import a git tree object into a bzr repository.
132
0.200.261 by Jelmer Vernooij
More formatting fixes.
133
    :param texts: VersionedFiles object to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
134
    :param path: Path in the tree
135
    :param tree: A git tree object
136
    :param inv: Inventory object
137
    """
138
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
139
    ie = inv.add_path(path, "directory", file_id)
0.200.288 by Jelmer Vernooij
Add test for init-repo.
140
    ie.revision = None
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
141
    parent_keys = []
142
    for pinv in parent_invs:
143
        if not file_id in pinv:
144
            continue
145
        try:
0.200.288 by Jelmer Vernooij
Add test for init-repo.
146
            tree_sha = shagitmap.lookup_tree(path, pinv[file_id].revision)
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
147
        except KeyError:
148
            pass
0.200.288 by Jelmer Vernooij
Add test for init-repo.
149
        else:
150
            if tree_sha == tree.id:
151
                ie.revision = pinv[file_id].revision
152
                break
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
153
        parent_keys.append((file_id, pinv[file_id].revision))
0.200.288 by Jelmer Vernooij
Add test for init-repo.
154
    if ie.revision is None:
155
        ie.revision = inv.revision_id
156
        texts.add_lines((file_id, ie.revision), parent_keys, [])
157
        shagitmap.add_entry(tree.id, "tree", (file_id, ie.revision))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
158
    for mode, name, hexsha in tree.entries():
159
        entry_kind = (mode & 0700000) / 0100000
160
        basename = name.decode("utf-8")
161
        if path == "":
162
            child_path = name
163
        else:
164
            child_path = urlutils.join(path, name)
0.200.264 by Jelmer Vernooij
Add more tests.
165
        obj = lookup_object(hexsha)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
166
        if entry_kind == 0:
0.200.264 by Jelmer Vernooij
Add more tests.
167
            import_git_tree(texts, mapping, child_path, obj, inv, parent_invs,
168
                shagitmap, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
169
        elif entry_kind == 1:
0.200.159 by Jelmer Vernooij
Fix branch tests.
170
            fs_mode = mode & 0777
0.200.264 by Jelmer Vernooij
Add more tests.
171
            import_git_blob(texts, mapping, child_path, obj, inv, parent_invs,
172
                shagitmap, bool(fs_mode & 0111))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
173
        else:
174
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
0.200.286 by Jelmer Vernooij
Prevent creating repeated directory texts.
175
    return ie
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
176
177
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
178
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
179
        pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
180
    """Import a set of git objects into a bzr repository.
181
182
    :param repo: Bazaar repository
183
    :param mapping: Mapping to use
184
    :param object_iter: Iterator over Git objects.
185
    """
186
    # TODO: a more (memory-)efficient implementation of this
0.200.158 by Jelmer Vernooij
fetch works \o/
187
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
188
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
189
    revisions = {}
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
190
    # Find and convert commit objects
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
191
    for o in object_iter.iterobjects():
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
192
        if isinstance(o, Commit):
193
            rev = mapping.import_commit(o)
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
194
            root_trees[rev.revision_id] = object_iter[o.tree]
0.200.158 by Jelmer Vernooij
fetch works \o/
195
            revisions[rev.revision_id] = rev
196
            graph.append((rev.revision_id, rev.parent_ids))
0.200.261 by Jelmer Vernooij
More formatting fixes.
197
            target_git_object_retriever._idmap.add_entry(o.sha().hexdigest(),
198
                "commit", (rev.revision_id, o._tree))
0.200.158 by Jelmer Vernooij
fetch works \o/
199
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
200
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
201
    for i, revid in enumerate(topo_sort(graph)):
202
        if pb is not None:
203
            pb.update("fetching revisions", i, len(graph))
204
        root_tree = root_trees[revid]
205
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
206
        # We have to do this here, since we have to walk the tree and 
207
        # we need to make sure to import the blobs / trees with the riht 
208
        # path; this may involve adding them more than once.
209
        inv = Inventory()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
210
        inv.revision_id = rev.revision_id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
211
        def lookup_object(sha):
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
212
            if sha in object_iter:
213
                return object_iter[sha]
0.200.230 by Jelmer Vernooij
Implement sha cache.
214
            return target_git_object_retriever[sha]
0.200.158 by Jelmer Vernooij
fetch works \o/
215
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
0.200.261 by Jelmer Vernooij
More formatting fixes.
216
        import_git_tree(repo.texts, mapping, "", root_tree, inv, parent_invs, 
0.200.264 by Jelmer Vernooij
Add more tests.
217
            target_git_object_retriever._idmap, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
218
        repo.add_revision(rev.revision_id, rev, inv)
0.200.272 by Jelmer Vernooij
Actually store idmap.
219
    target_git_object_retriever._idmap.commit()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
220
221
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
222
class InterGitNonGitRepository(InterRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
223
    """InterRepository that copies revisions from a Git into a non-Git 
224
    repository."""
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
225
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
226
    _matching_repo_format = GitRepositoryFormat()
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
227
228
    @staticmethod
229
    def _get_repo_format_to_test():
230
        return None
231
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
232
    def copy_content(self, revision_id=None, pb=None):
233
        """See InterRepository.copy_content."""
234
        self.fetch(revision_id, pb, find_ghosts=False)
235
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
236
    def fetch_objects(self, determine_wants, mapping, pb=None):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
237
        def progress(text):
0.217.41 by John Carr
Don't fill screen with muttering
238
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
239
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
240
        create_pb = None
241
        if pb is None:
242
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
243
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
244
        
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
245
        try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
246
            self.target.lock_write()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
247
            try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
248
                self.target.start_write_group()
249
                try:
0.200.216 by Jelmer Vernooij
Use ObjectIterator interface.
250
                    objects_iter = self.source.fetch_objects(determine_wants, 
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
251
                                graph_walker, 
252
                                target_git_object_retriever.__getitem__, 
253
                                progress)
254
                    import_git_objects(self.target, mapping, objects_iter, 
255
                            target_git_object_retriever, pb)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
256
                finally:
257
                    self.target.commit_write_group()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
258
            finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
259
                self.target.unlock()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
260
        finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
261
            if create_pb:
262
                create_pb.finished()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
263
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
264
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
265
              mapping=None, fetch_spec=None):
0.200.247 by Jelmer Vernooij
Fix git-import.
266
        self.fetch_refs(revision_id=revision_id, pb=pb, find_ghosts=find_ghosts,
267
                mapping=mapping, fetch_spec=fetch_spec)
268
269
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False, 
270
              mapping=None, fetch_spec=None):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
271
        if mapping is None:
272
            mapping = self.source.get_mapping()
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
273
        if revision_id is not None:
274
            interesting_heads = [revision_id]
275
        elif fetch_spec is not None:
276
            interesting_heads = fetch_spec.heads
277
        else:
278
            interesting_heads = None
0.200.247 by Jelmer Vernooij
Fix git-import.
279
        self._refs = {}
280
        def determine_wants(refs):
281
            self._refs = refs
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
282
            if interesting_heads is None:
0.200.247 by Jelmer Vernooij
Fix git-import.
283
                ret = [sha for (ref, sha) in refs.iteritems() if not ref.endswith("^{}")]
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
284
            else:
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
285
                ret = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in interesting_heads]
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
286
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
0.200.247 by Jelmer Vernooij
Fix git-import.
287
        self.fetch_objects(determine_wants, mapping, pb)
288
        return self._refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
289
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
290
    @staticmethod
291
    def is_compatible(source, target):
292
        """Be compatible with GitRepository."""
293
        # FIXME: Also check target uses VersionedFile
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
294
        return (isinstance(source, GitRepository) and 
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
295
                target.supports_rich_root() and
296
                not isinstance(target, GitRepository))
297
298
299
class InterGitRepository(InterRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
300
    """InterRepository that copies between Git repositories."""
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
301
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
302
    _matching_repo_format = GitRepositoryFormat()
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
303
304
    @staticmethod
305
    def _get_repo_format_to_test():
306
        return None
307
308
    def copy_content(self, revision_id=None, pb=None):
309
        """See InterRepository.copy_content."""
310
        self.fetch(revision_id, pb, find_ghosts=False)
311
312
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
313
              mapping=None, fetch_spec=None):
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
314
        if mapping is None:
315
            mapping = self.source.get_mapping()
316
        def progress(text):
0.200.261 by Jelmer Vernooij
More formatting fixes.
317
            trace.info("git: %s", text)
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
318
        r = self.target._git
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
319
        if revision_id is not None:
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
320
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
321
        elif fetch_spec is not None:
322
            args = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in fetch_spec.heads]
0.200.247 by Jelmer Vernooij
Fix git-import.
323
        if fetch_spec is None and revision_id is None:
324
            determine_wants = r.object_store.determine_wants_all
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
325
        else:
0.200.247 by Jelmer Vernooij
Fix git-import.
326
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
327
328
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
329
        f, commit = r.object_store.add_pack()
330
        try:
331
            self.source._git.fetch_pack(path, determine_wants, graphwalker, f.write, progress)
332
            f.close()
333
            commit()
334
        except:
335
            f.close()
336
            raise
337
338
    @staticmethod
339
    def is_compatible(source, target):
340
        """Be compatible with GitRepository."""
341
        return (isinstance(source, GitRepository) and 
342
                isinstance(target, GitRepository))