6 sys.path.insert(0, os.getenv("GITPYTHONLIB","."))
8 from git_remote_helpers.util import die, debug, warn
9 from git_remote_helpers.hg import util
10 from git_remote_helpers.hg.hg import GitHg
11 from git_remote_helpers.hg.exporter import GitExporter
12 from git_remote_helpers.hg.importer import GitImporter
13 from git_remote_helpers.hg.non_local import NonLocalHg
16 def get_repo(alias, url):
17 """Returns a hg.repository object initialized for usage.
21 from mercurial import hg, ui
23 die("Mercurial python libraries not installed")
27 if url.startswith("remote://"):
29 url = "file://%s" % url[9:]
32 source, revs, checkout = util.parseurl(ui.expandpath(url), ['default'])
33 repo = hg.repository(ui, source)
34 if repo.capable('branchmap'):
35 revs += repo.branchmap().keys()
38 hasher = hashlib.sha1()
39 hasher.update(repo.path)
40 repo.hash = hasher.hexdigest()
42 repo.get_base_path = lambda base: os.path.join(
43 base, 'info', 'fast-import', repo.hash)
45 prefix = 'refs/hg/%s/' % alias
46 debug("prefix: '%s'", prefix)
54 repo.git_hg = GitHg(warn)
55 repo.exporter = GitExporter(repo)
56 repo.importer = GitImporter(repo)
57 repo.non_local = NonLocalHg(repo)
59 repo.is_local = not remote and repo.local()
64 def local_repo(repo, path):
65 """Returns a hg.repository object initalized for usage.
68 local = repo.hg.repository(repo.ui, path)
70 local.git_hg = repo.git_hg
71 local.non_local = None
73 local.gitdir = repo.gitdir
74 local.alias = repo.alias
75 local.prefix = repo.prefix
76 local.revs = repo.revs
77 local.hash = repo.hash
78 local.get_base_path = repo.get_base_path
79 local.exporter = GitExporter(local)
80 local.importer = GitImporter(local)
81 local.is_local = repo.is_local
86 def do_capabilities(repo, args):
87 """Prints the supported capabilities.
95 if not read_one_line(repo):
96 die("Expected gitdir, got empty line")
98 print "*refspec refs/heads/*:%s*" % repo.prefix
100 dirname = repo.get_base_path(repo.gitdir)
102 if not os.path.exists(dirname):
105 path = os.path.join(dirname, 'git.marks')
107 print "*export-marks %s" % path
108 if os.path.exists(path):
109 print "*import-marks %s" % path
111 print # end capabilities
114 def do_list(repo, args):
115 """Lists all known references.
118 for ref in repo.revs:
119 debug("? refs/heads/%s", ref)
120 print "? refs/heads/%s" % ref
122 debug("@refs/heads/default HEAD")
123 print "@refs/heads/default HEAD"
128 def update_local_repo(repo):
129 """Updates (or clones) a local repo.
135 path = repo.non_local.clone(repo.gitdir)
136 repo.non_local.update(repo.gitdir)
137 repo = local_repo(repo, path)
141 def do_import(repo, args):
142 """Exports a fast-import stream from hg for git to import.
146 die("Import expects its ref seperately")
149 die("Need gitdir to import")
154 line = sys.stdin.readline()
157 refs.append(line.strip())
159 repo = update_local_repo(repo)
160 repo.exporter.setup(True, repo.gitdir, True, True)
162 repo.exporter.export_repo()
163 repo.exporter.export_branch('default', 'default')
165 repo.exporter.write_marks(repo.gitdir)
170 def do_export(repo, args):
171 """Imports a fast-import stream from git to hg.
175 die("Need gitdir to export")
180 line = sys.stdin.readline()
183 refs.append(line.strip())
185 local_repo = update_local_repo(repo)
186 local_repo.importer.do_import(local_repo.gitdir)
188 if not repo.is_local:
189 repo.non_local.push(repo.gitdir)
197 def do_gitdir(repo, args):
198 """Stores the location of the gitdir.
202 die("gitdir needs an argument")
204 repo.gitdir = ' '.join(args)
208 'capabilities': do_capabilities,
217 """Cleans up the url.
220 if value.startswith('hg::'):
223 # for local URLs (no protocol), remove a terminal
224 # /.hg and make sure the path is absolute
225 if value.find("://") == -1:
226 if value.endswith("/.hg"):
228 value = os.path.abspath(value)
233 def read_one_line(repo):
234 """Reads and processes one command.
237 line = sys.stdin.readline()
242 warn("Unexpected EOF")
245 cmdline = cmdline.strip().split()
247 debug("Got empty line, quitting")
248 # Blank line means we're about to quit
252 debug("Got command '%s' with args '%s'", cmd, ' '.join(cmdline))
254 if cmd not in COMMANDS:
255 die("Unknown command, %s", cmd)
263 warn("while flushing '%s' with args '%s'", str(cmd), str(cmdline))
270 """Starts a new remote helper for the specified repository.
274 die("Expecting exactly three arguments.")
277 if os.getenv("GIT_DEBUG_HG"):
278 import git_remote_helpers.util
279 git_remote_helpers.util.DEBUG = True
282 url = sanitize(args[2])
284 if not alias.isalnum():
285 warn("non-alnum alias '%s'", alias)
291 repo = get_repo(alias, url)
293 debug("Got arguments %s", args[1:])
298 more = read_one_line(repo)
300 if __name__ == '__main__':
301 sys.exit(main(sys.argv))