4 # hashlib is only available in python >= 2.5
12 from git_remote_helpers.util import debug, die, warn
15 class RemoteHelper(object):
18 'capabilities': self.do_capabilities,
20 'import': self.do_import,
21 'export': self.do_export,
24 def setup_repo(self, repo, alias):
25 """Returns a git repository object initialized for usage.
29 hasher.update(repo.path)
30 repo.hash = hasher.hexdigest()
32 repo.get_base_path = lambda base: os.path.join(
33 base, 'info', 'fast-import', repo.hash)
35 repo.gitdir = os.environ["GIT_DIR"]
38 def setup_local_repo(self, local, repo):
39 """Returns a git repository object initalized for usage.
41 local.non_local = None
42 local.gitdir = repo.gitdir
43 local.alias = repo.alias
44 local.prefix = repo.prefix
45 local.hash = repo.hash
46 local.get_base_path = repo.get_base_path
48 def do_capabilities(self, repo, args):
49 """Prints the supported capabilities.
54 print "refspec refs/heads/*:%s*" % repo.prefix
56 dirname = repo.get_base_path(repo.gitdir)
58 if not os.path.exists(dirname):
61 path = os.path.join(dirname, repo.marksfile)
63 print "*export-marks %s" % path
64 if os.path.exists(path):
65 print "*import-marks %s" % path
67 print # end capabilities
69 def update_local_repo(self, repo):
70 """Updates (or clones) a local repo.
76 path = repo.non_local.clone(repo.gitdir)
77 repo.non_local.update(repo.gitdir)
78 repo = self.local_repo(repo, path)
81 def do_import(self, repo, args):
82 """Exports a fast-import stream from testgit for git to import.
86 die("Import needs exactly one ref")
89 die("Need gitdir to import")
95 line = sys.stdin.readline()
98 if not line.startswith('import '):
99 die("Expected import line.")
101 # strip of leading 'import '
102 ref = line[7:].strip()
105 repo = self.update_local_repo(repo)
107 repo.exporter.export_repo(repo.gitdir, refs)
111 def do_export(self, repo, args):
112 """Imports a fast-import stream from git to testgit.
116 die("Need gitdir to export")
118 localrepo = self.update_local_repo(repo)
120 refs_before = self.get_refs(repo, repo.gitdir)
121 localrepo.importer.do_import(localrepo.gitdir)
122 refs_after = self.get_refs(repo, repo.gitdir)
126 for name, value in refs_after.iteritems():
127 if refs_before.get(name) == value:
130 changed[name] = value
133 repo.non_local.push(repo.gitdir)
139 def read_one_line(self, repo):
140 """Reads and processes one command.
143 line = sys.stdin.readline()
148 warn("Unexpected EOF")
151 cmdline = cmdline.strip().split()
153 # Blank line means we're about to quit
157 debug("Got command '%s' with args '%s'", cmd, ' '.join(cmdline))
159 if cmd not in self.commands:
160 die("Unknown command, %s", cmd)
162 func = self.commands[cmd]
168 def main(self, args):
169 """Starts a new remote helper for the specified repository.
173 die("Expecting exactly three arguments.")
176 if os.getenv("GIT_REMOTE_HELPER_DEBUG"):
177 import git_remote_helpers.util
178 git_remote_helpers.util.DEBUG = True
180 alias = self.sanitize(args[1])
181 url = self.sanitize(args[2])
183 if not alias.isalnum():
184 warn("non-alnum alias '%s'", alias)
190 repo = self.get_repo(alias, url)
192 debug("Got arguments %s", args[1:])
197 more = self.read_one_line(repo)
199 if __name__ == '__main__':
200 sys.exit(main(sys.argv))