/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
1
#!/usr/bin/env python
2
# vim: expandtab
3
4
# Copyright (C) 2011 Jelmer Vernooij <jelmer@apache.org>
5
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20
21
"""Remote helper for git for accessing bzr repositories."""
22
23
CAPABILITIES = ["fetch", "option", "push"]
24
25
import os
26
27
from bzrlib.controldir import ControlDir
28
from bzrlib.errors import NotBranchError, NoRepositoryPresent
29
from bzrlib.repository import InterRepository
30
from bzrlib.transport import get_transport_from_path
31
32
from bzrlib.plugins.git import (
33
    LocalGitProber,
34
    )
35
from bzrlib.plugins.git.dir import (
36
    BareLocalGitControlDirFormat,
37
    LocalGitControlDirFormat,
38
    )
39
40
from bzrlib.plugins.git.object_store import (
41
    get_object_store,
42
    )
43
from bzrlib.plugins.git.refs import (
44
    get_refs_container,
45
    ref_to_branch_name,
46
    )
47
from bzrlib.plugins.git.repository import (
48
    GitRepository,
49
    )
50
51
try:
52
    from bzrlib.plugins.fastimport import exporter as fastexporter
53
except ImportError:
0.200.1582 by Jelmer Vernooij
Print error when bzr-fastimport is not installed.
54
    fastexporter = None
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
55
else:
56
    CAPABILITIES.append("import")
57
58
def open_remote_dir(url):
59
    try:
60
        return ControlDir.open(url)
61
    except NotBranchError:
62
        return ControlDir.create(url)
63
64
65
def fetch(outf, wants, shortname, remote_dir, local_dir):
66
    remote_repo = remote_dir.find_repository()
67
    local_repo = local_dir.find_repository()
68
    inter = InterRepository.get(remote_repo, local_repo)
69
    def update_refs(heads):
70
        ret = {}
71
        for (sha1, ref) in wants:
72
            ret[ref] = (sha1, None)
73
        return ret
74
    if (isinstance(remote_repo, GitRepository) and
75
        isinstance(local_repo, GitRepository)):
76
        lossy = False
77
    else:
78
        lossy = True
79
    inter.fetch_refs(update_refs, lossy=lossy)
80
    outf.write("\n")
81
82
83
def push(outf, wants, shortname, remote_dir, local_dir):
84
    for (src_ref, dest_ref) in wants:
85
        local_branch = local_dir.open_branch(ref=src_ref)
86
        dest_branch_name = ref_to_branch_name(dest_ref)
87
        if dest_branch_name == "master":
88
            dest_branch_name = None
89
        try:
90
            remote_branch = remote_dir.open_branch(name=dest_branch_name)
91
        except NotBranchError:
92
            remote_branch = remote_dir.create_branch(name=dest_branch_name)
93
        local_branch.push(remote_branch)
94
        outf.write("ok %s\n" % dest_ref)
95
    outf.write("\n")
96
97
98
class RemoteHelper(object):
99
    """Git remote helper."""
100
101
    def __init__(self, local_dir, shortname, remote_dir):
102
        self.local_dir = local_dir
103
        self.shortname = shortname
104
        self.remote_dir = remote_dir
105
        self.batchcmd = None
106
        self.wants = []
107
108
    def cmd_capabilities(self, outf, argv):
109
        outf.write("\n".join(CAPABILITIES)+"\n\n")
110
111
    def cmd_list(self, outf, argv):
112
        try:
113
            repo = self.remote_dir.find_repository()
114
        except NoRepositoryPresent:
115
            repo = self.remote_dir.create_repository()
116
        object_store = get_object_store(repo)
117
        object_store.lock_read()
118
        try:
119
            refs = get_refs_container(self.remote_dir, object_store)
120
            for ref, git_sha1 in refs.as_dict().iteritems():
121
                outf.write("%s %s\n" % (git_sha1, ref))
122
            outf.write("\n")
123
        finally:
124
            object_store.unlock()
125
126
    def cmd_option(self, outf, argv):
127
        outf.write("unsupported\n")
128
129
    def cmd_fetch(self, outf, argv):
130
        if self.batchcmd not in (None, "fetch"):
131
            raise Exception("fetch command inside other batch command")
132
        self.wants.append(tuple(argv[1:]))
133
        self.batchcmd = "fetch"
134
135
    def cmd_push(self, outf, argv):
136
        if self.batchcmd not in (None, "push"):
137
            raise Exception("push command inside other batch command")
138
        self.wants.append(tuple(argv[1].split(":", 1)))
139
        self.batchcmd = "push"
140
141
    def cmd_import(self, outf, argv):
0.200.1582 by Jelmer Vernooij
Print error when bzr-fastimport is not installed.
142
        if fastexporter is None:
143
            raise Exception("install bzr-fastimport for 'import' command support")
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
144
        dest_branch_name = ref_to_branch_name(argv[1])
145
        if dest_branch_name == "master":
146
            dest_branch_name = None
147
        remote_branch = self.remote_dir.open_branch(name=dest_branch_name)
148
        exporter = fastexporter.BzrFastExporter(remote_branch,
0.200.1581 by Jelmer Vernooij
Fix support for newer versions of bzr-fastimport, add more tests.
149
            outf=outf, ref=argv[1],
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
150
            checkpoint=None, import_marks_file=None,
151
            export_marks_file=None, revision=None,
152
            verbose=None, plain_format=True,
153
            rewrite_tags=False)
154
        exporter.run()
155
156
    commands = {
157
        "capabilities": cmd_capabilities,
158
        "list": cmd_list,
159
        "option": cmd_option,
160
        "fetch": cmd_fetch,
161
        "push": cmd_push,
162
        "import": cmd_import,
163
        }
164
165
    def process(self, inf, outf):
166
        while True:
167
            l = inf.readline()
168
            if not l:
169
                break
170
            self.process_line(l, outf)
171
172
    def process_line(self, l, outf):
173
        argv = l.strip().split()
174
        if argv == []:
175
            if self.batchcmd == "fetch":
176
                fetch(outf, self.wants, self.shortname, self.remote_dir, self.local_dir)
177
            elif self.batchcmd == "push":
178
                push(outf, self.wants, self.shortname, self.remote_dir, self.local_dir)
179
            elif self.batchcmd is None:
180
                return
181
            else:
182
                raise AssertionError("invalid batch %r" % self.batchcmd)
183
            self.batchcmd = None
184
        else:
185
            try:
186
               self.commands[argv[0]](self, outf, argv)
187
            except KeyError:
188
               raise Exception("Unknown remote command %r" % argv)
189
        outf.flush()
190
191
192
def open_local_dir():
193
    try:
194
        git_path = os.environ["GIT_DIR"]
195
    except KeyError:
196
        git_transport = get_transport_from_path(".")
197
        git_format = LocalGitProber().probe_transport(git_transport)
198
    else:
199
        if git_path.endswith("/.git"):
200
            git_format = LocalGitControlDirFormat()
201
            git_path = git_path[:-4]
202
        else:
203
            git_format = BareLocalGitControlDirFormat()
204
        git_transport = get_transport_from_path(git_path)
205
206
    return git_format.open(git_transport)