/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to push.py

update copyright years

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
 
1
# Copyright (C) 2009-2010 Jelmer Vernooij <jelmer@samba.org>
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Push implementation that simply prints message saying push is not supported."""
18
18
 
19
19
from bzrlib import (
 
20
    errors,
20
21
    ui,
21
22
    )
22
23
from bzrlib.repository import (
26
27
    NULL_REVISION,
27
28
    )
28
29
 
29
 
from bzrlib.plugins.git.converter import (
30
 
    BazaarObjectStore,
31
 
    )
32
30
from bzrlib.plugins.git.errors import (
33
31
    NoPushSupport,
34
32
    )
35
 
from bzrlib.plugins.git.mapping import (
36
 
    inventory_to_tree_and_blobs,
37
 
    revision_to_commit,
 
33
from bzrlib.plugins.git.object_store import (
 
34
    BazaarObjectStore,
38
35
    )
39
36
from bzrlib.plugins.git.repository import (
40
37
    GitRepository,
 
38
    LocalGitRepository,
41
39
    GitRepositoryFormat,
42
40
    )
 
41
from bzrlib.plugins.git.remote import (
 
42
    RemoteGitRepository,
 
43
    )
43
44
 
44
45
 
45
46
class MissingObjectsIterator(object):
47
48
 
48
49
    """
49
50
 
50
 
    def __init__(self, source, mapping, pb=None):
 
51
    def __init__(self, store, source, pb=None):
51
52
        """Create a new missing objects iterator.
52
53
 
53
54
        """
54
55
        self.source = source
55
 
        self._object_store = BazaarObjectStore(self.source, mapping)
56
 
        self._revids = set()
57
 
        self._sent_shas = set()
 
56
        self._object_store = store
58
57
        self._pending = []
59
58
        self.pb = pb
60
59
 
61
60
    def import_revisions(self, revids):
62
 
        self._revids.update(revids)
63
61
        for i, revid in enumerate(revids):
64
62
            if self.pb:
65
63
                self.pb.update("pushing revisions", i, len(revids))
66
64
            git_commit = self.import_revision(revid)
67
65
            yield (revid, git_commit)
68
66
 
69
 
    def need_sha(self, sha):
70
 
        if sha in self._sent_shas:
71
 
            return False
72
 
        (type, (fileid, revid)) = self._object_store._idmap.lookup_git_sha(sha)
73
 
        assert type in ("blob", "tree")
74
 
        if revid in self._revids:
75
 
            # Not sent yet, and part of the set of revisions to send
76
 
            return True
77
 
        # Not changed in the revisions to send, so either not necessary
78
 
        # or already present remotely (as git doesn't do ghosts)
79
 
        return False
80
 
 
81
 
    def queue(self, sha, obj, path, ie=None, inv=None):
82
 
        if obj is None:
83
 
            obj = (ie, inv)
84
 
        self._pending.append((obj, path))
85
 
        self._sent_shas.add(sha)
86
 
 
87
67
    def import_revision(self, revid):
88
68
        """Import the gist of a revision into this Git repository.
89
69
 
90
70
        """
91
 
        inv = self.source.get_inventory(revid)
92
 
        todo = [inv.root]
93
 
        tree_sha = None
94
 
        while todo:
95
 
            ie = todo.pop()
96
 
            (sha, object) = self._object_store._get_ie_object_or_sha1(ie, inv)
97
 
            if ie.parent_id is None:
98
 
                tree_sha = sha
99
 
            if not self.need_sha(sha):
100
 
                continue
101
 
            self.queue(sha, object, inv.id2path(ie.file_id), ie, inv)
102
 
            if ie.kind == "directory":
103
 
                todo.extend(ie.children.values())
104
 
        assert tree_sha is not None
105
 
        commit = self._object_store._get_commit(revid, tree_sha)
106
 
        self.queue(commit.id, commit, None)
 
71
        tree = self._object_store.tree_cache.revision_tree(revid)
 
72
        rev = self.source.get_revision(revid)
 
73
        commit = None
 
74
        for path, obj, ie in self._object_store._revision_to_objects(rev, tree):
 
75
            if obj.type_name == "commit":
 
76
                commit = obj
 
77
            self._pending.append((obj, path))
107
78
        return commit.id
108
79
 
109
80
    def __len__(self):
110
81
        return len(self._pending)
111
82
 
112
83
    def __iter__(self):
113
 
        for i, (object, path) in enumerate(self._pending):
114
 
            if self.pb:
115
 
                self.pb.update("writing pack objects", i, len(self))
116
 
            if isinstance(object, tuple):
117
 
                object = self._object_store._get_ie_object(*object)
118
 
            yield (object, path)   
 
84
        return iter(self._pending)
119
85
 
120
86
 
121
87
class InterToGitRepository(InterRepository):
123
89
 
124
90
    _matching_repo_format = GitRepositoryFormat()
125
91
 
 
92
    def __init__(self, source, target):
 
93
        super(InterToGitRepository, self).__init__(source, target)
 
94
        self.mapping = self.target.get_mapping()
 
95
        self.source_store = BazaarObjectStore(self.source, self.mapping)
 
96
 
126
97
    @staticmethod
127
98
    def _get_repo_format_to_test():
128
99
        return None
131
102
        """See InterRepository.copy_content."""
132
103
        self.fetch(revision_id, pb, find_ghosts=False)
133
104
 
134
 
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
 
105
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
135
106
            fetch_spec=None):
136
107
        raise NoPushSupport()
137
108
 
138
 
    def missing_revisions(self, stop_revision):
139
 
        if stop_revision is None:
140
 
            raise NotImplementedError
 
109
 
 
110
class InterToLocalGitRepository(InterToGitRepository):
 
111
 
 
112
    def missing_revisions(self, stop_revisions, check_revid):
141
113
        missing = []
142
114
        pb = ui.ui_factory.nested_progress_bar()
143
115
        try:
144
116
            graph = self.source.get_graph()
145
 
            for revid, _ in graph.iter_ancestry([stop_revision]):
 
117
            for revid, _ in graph.iter_ancestry(stop_revisions):
146
118
                pb.update("determining revisions to fetch", len(missing))
147
 
                if not self.target.has_revision(revid):
 
119
                if not check_revid(revid):
148
120
                    missing.append(revid)
149
121
            return graph.iter_topo_order(missing)
150
122
        finally:
151
123
            pb.finished()
152
124
 
153
 
    def dfetch(self, stop_revision=None):
 
125
    def dfetch_refs(self, refs):
 
126
        old_refs = self.target._git.get_refs()
 
127
        new_refs = {}
 
128
        revidmap, gitidmap = self.dfetch(refs.values())
 
129
        for name, revid in refs.iteritems():
 
130
            if revid in gitidmap:
 
131
                gitid = gitidmap[revid]
 
132
            else:
 
133
                gitid = self.source_store._lookup_revision_sha1(revid)
 
134
            self.target._git.refs[name] = gitid
 
135
            new_refs[name] = gitid
 
136
        return revidmap, old_refs, new_refs
 
137
 
 
138
    def dfetch(self, stop_revisions):
154
139
        """Import the gist of the ancestry of a particular revision."""
 
140
        gitidmap = {}
155
141
        revidmap = {}
156
 
        mapping = self.target.get_mapping()
157
142
        self.source.lock_read()
158
143
        try:
159
 
            todo = [revid for revid in self.missing_revisions(stop_revision) if revid != NULL_REVISION]
 
144
            target_store = self.target._git.object_store
 
145
            def check_revid(revid):
 
146
                if revid == NULL_REVISION:
 
147
                    return True
 
148
                try:
 
149
                    return (self.source_store._lookup_revision_sha1(revid) in target_store)
 
150
                except errors.NoSuchRevision:
 
151
                    # Ghost, can't dpush
 
152
                    return True
 
153
            todo = list(self.missing_revisions(stop_revisions, check_revid))
160
154
            pb = ui.ui_factory.nested_progress_bar()
161
155
            try:
162
 
                object_generator = MissingObjectsIterator(self.source, mapping, pb)
 
156
                object_generator = MissingObjectsIterator(self.source_store, self.source, pb)
163
157
                for old_bzr_revid, git_commit in object_generator.import_revisions(
164
158
                    todo):
165
 
                    new_bzr_revid = mapping.revision_id_foreign_to_bzr(git_commit)
 
159
                    new_bzr_revid = self.mapping.revision_id_foreign_to_bzr(git_commit)
166
160
                    revidmap[old_bzr_revid] = new_bzr_revid
167
 
                self.target._git.object_store.add_objects(object_generator) 
 
161
                    gitidmap[old_bzr_revid] = git_commit
 
162
                target_store.add_objects(object_generator)
168
163
            finally:
169
164
                pb.finished()
170
165
        finally:
171
166
            self.source.unlock()
172
 
        return revidmap
173
 
 
174
 
    @staticmethod
175
 
    def is_compatible(source, target):
176
 
        """Be compatible with GitRepository."""
177
 
        return (not isinstance(source, GitRepository) and 
178
 
                isinstance(target, GitRepository))
 
167
        return revidmap, gitidmap
 
168
 
 
169
    @staticmethod
 
170
    def is_compatible(source, target):
 
171
        """Be compatible with GitRepository."""
 
172
        return (not isinstance(source, GitRepository) and
 
173
                isinstance(target, LocalGitRepository))
 
174
 
 
175
 
 
176
class InterToRemoteGitRepository(InterToGitRepository):
 
177
 
 
178
    def dfetch_refs(self, new_refs):
 
179
        """Import the gist of the ancestry of a particular revision."""
 
180
        revidmap = {}
 
181
        old_refs = {}
 
182
        def determine_wants(refs):
 
183
            ret = {}
 
184
            old_refs.update(new_refs)
 
185
            for name, revid in new_refs.iteritems():
 
186
                ret[name] = self.source_store._lookup_revision_sha1(revid)
 
187
            return ret
 
188
        self.source.lock_read()
 
189
        try:
 
190
            new_refs = self.target.send_pack(determine_wants,
 
191
                    self.source_store.generate_pack_contents)
 
192
        finally:
 
193
            self.source.unlock()
 
194
        return revidmap, old_refs, new_refs
 
195
 
 
196
    @staticmethod
 
197
    def is_compatible(source, target):
 
198
        """Be compatible with GitRepository."""
 
199
        return (not isinstance(source, GitRepository) and
 
200
                isinstance(target, RemoteGitRepository))