/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.217.1 by John Carr
Start stubbing out rewritten git-serve
1
# Copyright (C) 2008 Canonical Ltd
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.217.7 by John Carr
Create tips
17
from bzrlib.bzrdir import BzrDir
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
18
from bzrlib.repository import Repository
0.217.15 by John Carr
Start traversing commits and inventories
19
from bzrlib.inventory import InventoryDirectory, InventoryFile
0.217.21 by John Carr
This is oh so nearly the right logic, but it is so going to explode...
20
from bzrlib.osutils import splitpath
0.217.4 by John Carr
Easy bits of git pushing to bazaar
21
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
22
from bzrlib.plugins.git.fetch import import_git_objects
0.217.7 by John Carr
Create tips
23
from bzrlib.plugins.git.mapping import default_mapping
24
0.217.1 by John Carr
Start stubbing out rewritten git-serve
25
from dulwich.server import Backend
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
26
from dulwich.pack import Pack, PackData, write_pack_index_v2
0.217.17 by John Carr
More gentle plumbing
27
from dulwich.objects import ShaFile, Commit, Tree, Blob
0.217.5 by John Carr
Add a temporary hack to test pushing form git to bazaar
28
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
29
import os, tempfile
0.217.1 by John Carr
Start stubbing out rewritten git-serve
30
0.217.45 by John Carr
Restore +x flag is file is executable
31
import stat
0.217.44 by John Carr
Use proper modes
32
S_IFGITLINK = 0160000
33
0.217.46 by John Carr
Remove debug print. Fetch S_IF* foo from stat module. Fix file mode picker.
34
#S_IFREG | 0664 # *Might* see this; would fail fsck --strict
0.217.44 by John Carr
Use proper modes
35
0.217.32 by John Carr
Dirtyness to help pass tests
36
0.217.1 by John Carr
Start stubbing out rewritten git-serve
37
class BzrBackend(Backend):
38
0.217.2 by John Carr
Fix missing imports. Update TCPGitServer instantiation to latest. BzrBackend needs to know which directory its repo is in.
39
    def __init__(self, directory):
40
        self.directory = directory
0.217.7 by John Carr
Create tips
41
        self.mapping = default_mapping
0.217.2 by John Carr
Fix missing imports. Update TCPGitServer instantiation to latest. BzrBackend needs to know which directory its repo is in.
42
0.217.1 by John Carr
Start stubbing out rewritten git-serve
43
    def get_refs(self):
44
        """ return a dict of all tags and branches in repository (and shas) """
0.217.12 by John Carr
Support ls-remote against bazaar
45
        ret = {}
46
        repo_dir = BzrDir.open(self.directory)
47
        repo = repo_dir.open_repository()
0.217.52 by John Carr
Have a head, any head
48
        branch = None
0.217.12 by John Carr
Support ls-remote against bazaar
49
        for branch in repo.find_branches(using=True):
0.217.52 by John Carr
Have a head, any head
50
            #FIXME: Look for 'master' or 'trunk' in here, and set HEAD accordingly...
0.217.12 by John Carr
Support ls-remote against bazaar
51
            #FIXME: Need to get branch path relative to its repository and use this instead of nick
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
52
            ret["refs/heads/"+branch.nick] = self.mapping.revision_id_bzr_to_foreign(branch.last_revision())[0]
0.217.52 by John Carr
Have a head, any head
53
        if 'HEAD' not in ret and branch:
0.217.56 by John Carr
Merge upstream
54
            ret['HEAD'] = self.mapping.revision_id_bzr_to_foreign(branch.last_revision())[0]
0.217.12 by John Carr
Support ls-remote against bazaar
55
        return ret
0.217.1 by John Carr
Start stubbing out rewritten git-serve
56
57
    def apply_pack(self, refs, read):
58
        """ apply pack from client to current repository """
0.217.4 by John Carr
Easy bits of git pushing to bazaar
59
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
60
        fd, path = tempfile.mkstemp(suffix=".pack")
61
        f = os.fdopen(fd, 'w')
0.217.6 by John Carr
Fix typos
62
        f.write(read())
0.217.5 by John Carr
Add a temporary hack to test pushing form git to bazaar
63
        f.close()
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
64
65
        p = PackData(path)
66
        entries = p.sorted_entries()
67
        write_pack_index_v2(path[:-5]+".idx", entries, p.calculate_checksum())
68
69
        def get_objects():
70
            pack = Pack(path[:-5])
71
            for obj in pack.iterobjects():
72
                yield obj
73
74
        target = Repository.open(self.directory)
75
76
        target.lock_write()
0.217.4 by John Carr
Easy bits of git pushing to bazaar
77
        try:
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
78
            target.start_write_group()
79
            try:
80
                import_git_objects(target, self.mapping, iter(get_objects()))
81
            finally:
82
                target.commit_write_group()
0.217.4 by John Carr
Easy bits of git pushing to bazaar
83
        finally:
0.217.8 by John Carr
Don't bother using InterRepo, use import_git_objects directly. Don't need a full repository (just operating on a pack and index)
84
            target.unlock()
0.217.4 by John Carr
Easy bits of git pushing to bazaar
85
0.217.7 by John Carr
Create tips
86
        for oldsha, sha, ref in refs:
87
            if ref[:11] == 'refs/heads/':
88
                branch_nick = ref[11:]
89
90
                try:
91
                    target_dir = BzrDir.open(self.directory + "/" + branch_nick)
92
                except:
93
                    target_dir = BzrDir.create(self.directory + "/" + branch_nick)
94
95
                try:
96
                    target_branch = target_dir.open_branch()
97
                except:
98
                    target_branch = target_dir.create_branch()
0.217.22 by John Carr
Fix whitespace
99
0.217.7 by John Carr
Create tips
100
                rev_id = self.mapping.revision_id_foreign_to_bzr(sha)
0.217.22 by John Carr
Fix whitespace
101
                target_branch.generate_revision_history(rev_id)
0.217.7 by John Carr
Create tips
102
0.217.1 by John Carr
Start stubbing out rewritten git-serve
103
    def fetch_objects(self, determine_wants, graph_walker, progress):
104
        """ yield git objects to send to client """
0.217.12 by John Carr
Support ls-remote against bazaar
105
        wants = determine_wants(self.get_refs())
0.217.14 by John Carr
Negotiate which revisions need to be sent to client, and iterate over them all
106
        commits_to_send = set([self.mapping.revision_id_foreign_to_bzr(w) for w in wants])
107
        rev_done = set()
0.217.31 by John Carr
At the moment, we have to convert an object to know its sha :\ - the same sha can be made multiple times... lets at least not add it the pack if its already there.
108
        obj_sent = set()
0.217.14 by John Carr
Negotiate which revisions need to be sent to client, and iterate over them all
109
110
        repo = Repository.open(self.directory)
0.217.22 by John Carr
Fix whitespace
111
0.200.188 by Jelmer Vernooij
Merge dulwich.
112
        objects = set()
113
0.217.14 by John Carr
Negotiate which revisions need to be sent to client, and iterate over them all
114
        repo.lock_read()
115
        try:
116
            have = graph_walker.next()
117
            while have:
118
                rev_done.add(have)
119
                if repo.has_revision(self.mapping.revision_id_foregin_to_bzr(sha)):
120
                    graph_walker.ack(have)
121
                have = graph_walker.next()
122
123
            while commits_to_send:
0.217.15 by John Carr
Start traversing commits and inventories
124
                commit = commits_to_send.pop()
0.217.14 by John Carr
Negotiate which revisions need to be sent to client, and iterate over them all
125
                if commit in rev_done:
126
                    continue
127
                rev_done.add(commit)
128
0.217.15 by John Carr
Start traversing commits and inventories
129
                rev = repo.get_revision(commit)
130
131
                commits_to_send.update([p for p in rev.parent_ids if not p in rev_done])
132
0.217.50 by John Carr
Make fetch_objects return a list of (object, path)
133
                for sha, obj, path in inventory_to_tree_and_blobs(repo, self.mapping, commit):
0.217.31 by John Carr
At the moment, we have to convert an object to know its sha :\ - the same sha can be made multiple times... lets at least not add it the pack if its already there.
134
                    if sha not in obj_sent:
135
                        obj_sent.add(sha)
0.217.50 by John Carr
Make fetch_objects return a list of (object, path)
136
                        objects.add((obj, path))
0.217.15 by John Carr
Start traversing commits and inventories
137
0.223.1 by Jelmer Vernooij
Move revision_to_commit onto mapping.
138
                objects.add((mapping.export_commit(rev, sha), None))
0.217.15 by John Carr
Start traversing commits and inventories
139
0.217.14 by John Carr
Negotiate which revisions need to be sent to client, and iterate over them all
140
        finally:
141
            repo.unlock()
0.217.15 by John Carr
Start traversing commits and inventories
142
0.200.188 by Jelmer Vernooij
Merge dulwich.
143
        return (len(objects), iter(objects))
144
0.217.15 by John Carr
Start traversing commits and inventories
145
0.217.33 by John Carr
Return real full texts
146
def inventory_to_tree_and_blobs(repo, mapping, revision_id):
0.217.20 by John Carr
Refactor to track Tree objects as we iterate over inventory
147
    stack = []
148
    cur = ""
149
    tree = Tree()
0.217.15 by John Carr
Start traversing commits and inventories
150
0.217.33 by John Carr
Return real full texts
151
    inv = repo.get_inventory(revision_id)
152
0.217.15 by John Carr
Start traversing commits and inventories
153
    for path, entry in inv.iter_entries():
0.217.20 by John Carr
Refactor to track Tree objects as we iterate over inventory
154
        while stack and not path.startswith(cur):
155
            tree.serialize()
0.217.28 by John Carr
Refactor to correctly yield shas and objects
156
            sha = tree.sha().hexdigest()
0.217.50 by John Carr
Make fetch_objects return a list of (object, path)
157
            yield sha, tree, path
0.217.46 by John Carr
Remove debug print. Fetch S_IF* foo from stat module. Fix file mode picker.
158
            t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha)
0.217.21 by John Carr
This is oh so nearly the right logic, but it is so going to explode...
159
            cur, tree = stack.pop()
0.217.30 by John Carr
Typo
160
            tree.add(*t)
0.217.15 by John Carr
Start traversing commits and inventories
161
162
        if type(entry) == InventoryDirectory:
0.217.20 by John Carr
Refactor to track Tree objects as we iterate over inventory
163
            stack.append((cur, tree))
164
            cur = path
165
            tree = Tree()
0.217.15 by John Carr
Start traversing commits and inventories
166
167
        if type(entry) == InventoryFile:
0.217.33 by John Carr
Return real full texts
168
            #FIXME: We can make potentially make this Lazy to avoid shaing lots of stuff
169
            # and having all these objects in memory at once
0.217.17 by John Carr
More gentle plumbing
170
            blob = Blob()
0.217.40 by John Carr
Use entry file_id
171
            _, blob._text = repo.iter_files_bytes([(entry.file_id, revision_id, path)]).next()
0.217.28 by John Carr
Refactor to correctly yield shas and objects
172
            sha = blob.sha().hexdigest()
0.217.50 by John Carr
Make fetch_objects return a list of (object, path)
173
            yield sha, blob, path
0.217.15 by John Carr
Start traversing commits and inventories
174
0.217.38 by John Carr
Fix encoding problem
175
            name = splitpath(path)[-1:][0].encode('UTF-8')
0.217.46 by John Carr
Remove debug print. Fetch S_IF* foo from stat module. Fix file mode picker.
176
            mode = stat.S_IFREG | 0644
177
            if entry.executable:
178
                mode |= 0111
0.217.38 by John Carr
Fix encoding problem
179
            tree.add(mode, name, sha)
0.217.21 by John Carr
This is oh so nearly the right logic, but it is so going to explode...
180
0.217.28 by John Carr
Refactor to correctly yield shas and objects
181
    while len(stack) > 1:
0.217.20 by John Carr
Refactor to track Tree objects as we iterate over inventory
182
        tree.serialize()
0.217.28 by John Carr
Refactor to correctly yield shas and objects
183
        sha = tree.sha().hexdigest()
0.217.50 by John Carr
Make fetch_objects return a list of (object, path)
184
        yield sha, tree, path
0.217.46 by John Carr
Remove debug print. Fetch S_IF* foo from stat module. Fix file mode picker.
185
        t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha)
0.217.21 by John Carr
This is oh so nearly the right logic, but it is so going to explode...
186
        cur, tree = stack.pop()
0.217.30 by John Carr
Typo
187
        tree.add(*t)
0.217.28 by John Carr
Refactor to correctly yield shas and objects
188
189
    tree.serialize()
0.217.50 by John Carr
Make fetch_objects return a list of (object, path)
190
    yield tree.sha().hexdigest(), tree, path
0.217.15 by John Carr
Start traversing commits and inventories
191