/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)
0.200.1586 by Jelmer Vernooij
Fixes duplicate tag warnings in 'git-remote-bzr' helper.
69
    revs = []
70
    for (sha1, ref) in wants:
71
        revs.append((sha1, None))
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
72
    if (isinstance(remote_repo, GitRepository) and
73
        isinstance(local_repo, GitRepository)):
74
        lossy = False
75
    else:
76
        lossy = True
0.200.1586 by Jelmer Vernooij
Fixes duplicate tag warnings in 'git-remote-bzr' helper.
77
    inter.fetch_objects(revs, lossy=lossy)
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
78
    outf.write("\n")
79
80
81
def push(outf, wants, shortname, remote_dir, local_dir):
82
    for (src_ref, dest_ref) in wants:
83
        local_branch = local_dir.open_branch(ref=src_ref)
84
        dest_branch_name = ref_to_branch_name(dest_ref)
85
        if dest_branch_name == "master":
86
            dest_branch_name = None
87
        try:
88
            remote_branch = remote_dir.open_branch(name=dest_branch_name)
89
        except NotBranchError:
90
            remote_branch = remote_dir.create_branch(name=dest_branch_name)
91
        local_branch.push(remote_branch)
92
        outf.write("ok %s\n" % dest_ref)
93
    outf.write("\n")
94
95
96
class RemoteHelper(object):
97
    """Git remote helper."""
98
99
    def __init__(self, local_dir, shortname, remote_dir):
100
        self.local_dir = local_dir
101
        self.shortname = shortname
102
        self.remote_dir = remote_dir
103
        self.batchcmd = None
104
        self.wants = []
105
106
    def cmd_capabilities(self, outf, argv):
107
        outf.write("\n".join(CAPABILITIES)+"\n\n")
108
109
    def cmd_list(self, outf, argv):
110
        try:
111
            repo = self.remote_dir.find_repository()
112
        except NoRepositoryPresent:
113
            repo = self.remote_dir.create_repository()
114
        object_store = get_object_store(repo)
115
        object_store.lock_read()
116
        try:
117
            refs = get_refs_container(self.remote_dir, object_store)
118
            for ref, git_sha1 in refs.as_dict().iteritems():
119
                outf.write("%s %s\n" % (git_sha1, ref))
120
            outf.write("\n")
121
        finally:
122
            object_store.unlock()
123
124
    def cmd_option(self, outf, argv):
125
        outf.write("unsupported\n")
126
127
    def cmd_fetch(self, outf, argv):
128
        if self.batchcmd not in (None, "fetch"):
129
            raise Exception("fetch command inside other batch command")
130
        self.wants.append(tuple(argv[1:]))
131
        self.batchcmd = "fetch"
132
133
    def cmd_push(self, outf, argv):
134
        if self.batchcmd not in (None, "push"):
135
            raise Exception("push command inside other batch command")
136
        self.wants.append(tuple(argv[1].split(":", 1)))
137
        self.batchcmd = "push"
138
139
    def cmd_import(self, outf, argv):
0.200.1582 by Jelmer Vernooij
Print error when bzr-fastimport is not installed.
140
        if fastexporter is None:
141
            raise Exception("install bzr-fastimport for 'import' command support")
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
142
        dest_branch_name = ref_to_branch_name(argv[1])
143
        if dest_branch_name == "master":
144
            dest_branch_name = None
145
        remote_branch = self.remote_dir.open_branch(name=dest_branch_name)
146
        exporter = fastexporter.BzrFastExporter(remote_branch,
0.200.1581 by Jelmer Vernooij
Fix support for newer versions of bzr-fastimport, add more tests.
147
            outf=outf, ref=argv[1],
0.200.1514 by Jelmer Vernooij
Move git_remote_helper to a python module.
148
            checkpoint=None, import_marks_file=None,
149
            export_marks_file=None, revision=None,
150
            verbose=None, plain_format=True,
151
            rewrite_tags=False)
152
        exporter.run()
153
154
    commands = {
155
        "capabilities": cmd_capabilities,
156
        "list": cmd_list,
157
        "option": cmd_option,
158
        "fetch": cmd_fetch,
159
        "push": cmd_push,
160
        "import": cmd_import,
161
        }
162
163
    def process(self, inf, outf):
164
        while True:
165
            l = inf.readline()
166
            if not l:
167
                break
168
            self.process_line(l, outf)
169
170
    def process_line(self, l, outf):
171
        argv = l.strip().split()
172
        if argv == []:
173
            if self.batchcmd == "fetch":
174
                fetch(outf, self.wants, self.shortname, self.remote_dir, self.local_dir)
175
            elif self.batchcmd == "push":
176
                push(outf, self.wants, self.shortname, self.remote_dir, self.local_dir)
177
            elif self.batchcmd is None:
178
                return
179
            else:
180
                raise AssertionError("invalid batch %r" % self.batchcmd)
181
            self.batchcmd = None
182
        else:
183
            try:
184
               self.commands[argv[0]](self, outf, argv)
185
            except KeyError:
186
               raise Exception("Unknown remote command %r" % argv)
187
        outf.flush()
188
189
190
def open_local_dir():
191
    try:
192
        git_path = os.environ["GIT_DIR"]
193
    except KeyError:
194
        git_transport = get_transport_from_path(".")
195
        git_format = LocalGitProber().probe_transport(git_transport)
196
    else:
197
        if git_path.endswith("/.git"):
198
            git_format = LocalGitControlDirFormat()
199
            git_path = git_path[:-4]
200
        else:
201
            git_format = BareLocalGitControlDirFormat()
202
        git_transport = get_transport_from_path(git_path)
203
204
    return git_format.open(git_transport)