/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 server.py

Implement GitRepository.revision_graph_can_have_wrong_parents().

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import os
18
 
import stat
19
18
import tempfile
20
19
 
 
20
from dulwich.server import TCPGitServer
 
21
import os
 
22
 
21
23
from bzrlib.bzrdir import (
22
24
    BzrDir,
23
 
    )
24
 
from bzrlib.inventory import (
25
 
    InventoryDirectory,
26
 
    InventoryFile,
27
 
    )
28
 
from bzrlib.osutils import (
29
 
    splitpath,
 
25
    BzrDirFormat,
30
26
    )
31
27
from bzrlib.repository import (
32
28
    Repository,
34
30
 
35
31
from bzrlib.plugins.git.fetch import (
36
32
    import_git_objects,
 
33
    BazaarObjectStore,
37
34
    )
38
35
from bzrlib.plugins.git.mapping import (
39
36
    default_mapping,
40
 
    inventory_to_tree_and_blobs,
41
 
    revision_to_commit,
 
37
    )
 
38
from bzrlib.plugins.git.object_store import (
 
39
    get_object_store
42
40
    )
43
41
 
44
42
from dulwich.server import (
49
47
    PackData,
50
48
    write_pack_index_v2,
51
49
    )
52
 
from dulwich.objects import (
53
 
    Blob,
54
 
    Commit,
55
 
    ShaFile,
56
 
    Tree,
57
 
    )
58
 
 
59
 
S_IFGITLINK = 0160000
60
 
 
61
 
#S_IFREG | 0664 # *Might* see this; would fail fsck --strict
62
50
 
63
51
 
64
52
class BzrBackend(Backend):
65
53
 
66
 
    def __init__(self, directory):
67
 
        self.directory = directory
 
54
    def __init__(self, transport):
 
55
        self.transport = transport
68
56
        self.mapping = default_mapping
69
57
 
70
58
    def get_refs(self):
71
59
        """ return a dict of all tags and branches in repository (and shas) """
72
60
        ret = {}
73
 
        repo_dir = BzrDir.open(self.directory)
74
 
        repo = repo_dir.open_repository()
75
 
        branch = None
76
 
        for branch in repo.find_branches(using=True):
77
 
            #FIXME: Look for 'master' or 'trunk' in here, and set HEAD accordingly...
78
 
            #FIXME: Need to get branch path relative to its repository and use this instead of nick
79
 
            ret["refs/heads/"+branch.nick] = self.mapping.revision_id_bzr_to_foreign(branch.last_revision())[0]
80
 
        if 'HEAD' not in ret and branch:
81
 
            ret['HEAD'] = self.mapping.revision_id_bzr_to_foreign(branch.last_revision())[0]
 
61
        repo_dir = BzrDir.open_from_transport(self.transport)
 
62
        repo = repo_dir.find_repository()
 
63
        repo.lock_read()
 
64
        try:
 
65
            store = get_object_store(repo)
 
66
            branch = None
 
67
            for branch in repo.find_branches(using=True):
 
68
                #FIXME: Look for 'master' or 'trunk' in here, and set HEAD accordingly...
 
69
                #FIXME: Need to get branch path relative to its repository and use this instead of nick
 
70
                ret["refs/heads/"+branch.nick] = store._lookup_revision_sha1(branch.last_revision())
 
71
            if 'HEAD' not in ret and branch:
 
72
                ret['HEAD'] = store._lookup_revision_sha1(branch.last_revision())
 
73
        finally:
 
74
            repo.unlock()
82
75
        return ret
83
76
 
84
77
    def apply_pack(self, refs, read):
98
91
            for obj in pack.iterobjects():
99
92
                yield obj
100
93
 
101
 
        target = Repository.open(self.directory)
 
94
        target = Repository.open_from_transport(self.transport)
102
95
 
103
96
        target.lock_write()
104
97
        try:
113
106
        for oldsha, sha, ref in refs:
114
107
            if ref[:11] == 'refs/heads/':
115
108
                branch_nick = ref[11:]
 
109
                transport = self.transport.clone(branch_nick)
116
110
 
117
111
                try:
118
 
                    target_dir = BzrDir.open(self.directory + "/" + branch_nick)
 
112
                    target_dir = BzrDir.open_from_transport(transport)
119
113
                except:
120
 
                    target_dir = BzrDir.create(self.directory + "/" + branch_nick)
 
114
                    format = BzrDirFormat.get_default_format()
 
115
                    format.initialize_on_transport(transport)
121
116
 
122
117
                try:
123
118
                    target_branch = target_dir.open_branch()
129
124
 
130
125
    def fetch_objects(self, determine_wants, graph_walker, progress):
131
126
        """ yield git objects to send to client """
132
 
        repo = Repository.open(self.directory)
 
127
        bzrdir = BzrDir.open_from_transport(self.transport)
 
128
        repo = bzrdir.find_repository()
133
129
 
134
130
        # If this is a Git repository, just use the existing fetch_objects implementation.
135
 
        if getattr(repo, "fetch_objects", None) is None:
 
131
        if getattr(repo, "fetch_objects", None) is not None:
136
132
            return repo.fetch_objects(determine_wants, graph_walker, None, progress)
137
133
 
138
134
        wants = determine_wants(self.get_refs())
139
 
        commits_to_send = set([self.mapping.revision_id_foreign_to_bzr(w) for w in wants])
140
 
        rev_done = set()
141
 
        obj_sent = set()
142
 
 
143
 
        objects = set()
144
 
 
145
135
        repo.lock_read()
146
 
        try:
147
 
            have = graph_walker.next()
148
 
            while have:
149
 
                rev_done.add(have)
150
 
                if repo.has_revision(self.mapping.revision_id_foreign_to_bzr(sha)):
151
 
                    graph_walker.ack(have)
152
 
                have = graph_walker.next()
153
 
 
154
 
            while commits_to_send:
155
 
                commit = commits_to_send.pop()
156
 
                if commit in rev_done:
157
 
                    continue
158
 
                rev_done.add(commit)
159
 
 
160
 
                rev = repo.get_revision(commit)
161
 
 
162
 
                commits_to_send.update([p for p in rev.parent_ids if not p in rev_done])
163
 
 
164
 
                for sha, obj, path in inventory_to_tree_and_blobs(repo, self.mapping, commit):
165
 
                    if sha not in obj_sent:
166
 
                        obj_sent.add(sha)
167
 
                        objects.add((obj, path))
168
 
 
169
 
                objects.add((revision_to_commit(rev, sha, self.mapping.revision_id_bzr_to_foreign), None))
170
 
 
171
 
        finally:
172
 
            repo.unlock()
173
 
 
174
 
        return (len(objects), iter(objects))
175
 
 
 
136
        store = BazaarObjectStore(repo)
 
137
        have = store.find_common_revisions(graph_walker)
 
138
        missing_sha1s = store.find_missing_objects(have, wants, progress)
 
139
        return store.iter_shas(missing_sha1s)
 
140
 
 
141
 
 
142
def serve_git(transport, host=None, port=None, inet=False):
 
143
    backend = BzrBackend(transport)
 
144
 
 
145
    server = TCPGitServer(backend, 'localhost')
 
146
    server.serve_forever()