5 # hashlib is only available in python >= 2.5
13 from git_remote_helpers
.util
import debug
, die
, warn
16 class RemoteHelper(object):
19 'capabilities': self
.do_capabilities
,
21 'import': self
.do_import
,
22 'export': self
.do_export
,
25 def setup_repo(self
, repo
, alias
):
26 """Returns a git repository object initialized for usage.
30 hasher
.update(repo
.path
)
31 repo
.hash = hasher
.hexdigest()
33 repo
.get_base_path
= lambda base
: os
.path
.join(
34 base
, 'info', 'fast-import', repo
.hash)
36 repo
.gitdir
= os
.environ
["GIT_DIR"]
39 def setup_local_repo(self
, local
, repo
):
40 """Returns a git repository object initalized for usage.
42 local
.non_local
= None
43 local
.gitdir
= repo
.gitdir
44 local
.alias
= repo
.alias
45 local
.prefix
= repo
.prefix
46 local
.hash = repo
.hash
47 local
.get_base_path
= repo
.get_base_path
49 def do_capabilities(self
, repo
, args
):
50 """Prints the supported capabilities.
55 print "refspec refs/heads/*:%s*" % repo
.prefix
57 dirname
= repo
.get_base_path(repo
.gitdir
)
59 if not os
.path
.exists(dirname
):
62 path
= os
.path
.join(dirname
, repo
.marksfile
)
64 print "*export-marks %s" % path
65 if os
.path
.exists(path
):
66 print "*import-marks %s" % path
68 print # end capabilities
70 def update_local_repo(self
, repo
):
71 """Updates (or clones) a local repo.
77 path
= repo
.non_local
.clone(repo
.gitdir
)
78 repo
.non_local
.update(repo
.gitdir
)
79 repo
= self
.local_repo(repo
, path
)
82 def do_import(self
, repo
, args
):
83 """Exports a fast-import stream from testgit for git to import.
87 die("Import needs exactly one ref")
90 die("Need gitdir to import")
96 line
= sys
.stdin
.readline()
99 if not line
.startswith('import '):
100 die("Expected import line.")
102 # strip of leading 'import '
103 ref
= line
[7:].strip()
106 repo
= self
.update_local_repo(repo
)
108 repo
.exporter
.export_repo(repo
.gitdir
, refs
)
112 def do_export(self
, repo
, args
):
113 """Imports a fast-import stream from git to testgit.
117 die("Need gitdir to export")
119 localrepo
= self
.update_local_repo(repo
)
121 refs_before
= self
.get_refs(repo
, repo
.gitdir
)
122 localrepo
.importer
.do_import(localrepo
.gitdir
)
123 refs_after
= self
.get_refs(repo
, repo
.gitdir
)
127 for name
, value
in refs_after
.iteritems():
128 if refs_before
.get(name
) == value
:
131 changed
[name
] = value
134 repo
.non_local
.push(repo
.gitdir
)
140 def read_one_line(self
, repo
):
141 """Reads and processes one command.
144 sleepy
= os
.environ
.get("GIT_REMOTE_TESTGIT_SLEEPY")
146 debug("Sleeping %d sec before readline" % int(sleepy
))
147 time
.sleep(int(sleepy
))
149 line
= sys
.stdin
.readline()
154 warn("Unexpected EOF")
157 cmdline
= cmdline
.strip().split()
159 # Blank line means we're about to quit
163 debug("Got command '%s' with args '%s'", cmd
, ' '.join(cmdline
))
165 if cmd
not in self
.commands
:
166 die("Unknown command, %s", cmd
)
168 func
= self
.commands
[cmd
]
174 def main(self
, args
):
175 """Starts a new remote helper for the specified repository.
179 die("Expecting exactly three arguments.")
182 if os
.getenv("GIT_REMOTE_HELPER_DEBUG"):
183 import git_remote_helpers
.util
184 git_remote_helpers
.util
.DEBUG
= True
186 alias
= self
.sanitize(args
[1])
187 url
= self
.sanitize(args
[2])
189 if not alias
.isalnum():
190 warn("non-alnum alias '%s'", alias
)
196 repo
= self
.get_repo(alias
, url
)
198 debug("Got arguments %s", args
[1:])
202 sys
.stdin
= os
.fdopen(sys
.stdin
.fileno(), 'r', 0)
204 more
= self
.read_one_line(repo
)
206 if __name__
== '__main__':
207 sys
.exit(main(sys
.argv
))