def get_repo(alias, url): """Returns a hg.repository object initialized for usage. """ try: from mercurial import hg, ui except ImportError: die("Mercurial python libraries not installed") ui = ui.ui() source, revs = hg.parseurl(ui.expandpath(url), ['tip']) repo = hg.repository(ui, source) prefix = 'refs/hg/%s/' % alias debug("prefix: '%s'", prefix) repo.hg = hg repo.gitdir = "" repo.alias = alias repo.prefix = prefix repo.revs = revs repo.git_hg = GitHg(warn) exporter = GitExporter(repo.git_hg, repo, 'hg.marks', 'git.marks', prefix) non_local = NonLocalHg(repo, alias) repo.exporter = exporter repo.non_local = non_local return repo
def main(args): """Starts a new remote helper for the specified repository. """ if len(args) != 3: die("Expecting exactly three arguments.") sys.exit(1) if os.getenv("GIT_DEBUG_TESTGIT"): import git_remote_helpers.util git_remote_helpers.util.DEBUG = True alias = sanitize(args[1]) url = sanitize(args[2]) if not alias.isalnum(): warn("non-alnum alias '%s'", alias) alias = "tmp" args[1] = alias args[2] = url repo = get_repo(alias, url) debug("Got arguments %s", args[1:]) more = True while (more): more = read_one_line(repo)
def read_one_line(repo): """Reads and processes one command. """ line = sys.stdin.readline() cmdline = line if not cmdline: warn("Unexpected EOF") return False cmdline = cmdline.strip().split() if not cmdline: # Blank line means we're about to quit return False cmd = cmdline.pop(0) debug("Got command '%s' with args '%s'", cmd, ' '.join(cmdline)) if cmd not in COMMANDS: die("Unknown command, %s", cmd) func = COMMANDS[cmd] func(repo, cmdline) sys.stdout.flush() return True
def read_one_line(self, repo): """Reads and processes one command. """ sleepy = os.environ.get("GIT_REMOTE_TESTGIT_SLEEPY") if sleepy: debug("Sleeping %d sec before readline" % int(sleepy)) time.sleep(int(sleepy)) line = sys.stdin.readline() cmdline = line if not cmdline: warn("Unexpected EOF") return False cmdline = cmdline.strip().split() if not cmdline: # Blank line means we're about to quit return False cmd = cmdline.pop(0) debug("Got command '%s' with args '%s'", cmd, " ".join(cmdline)) if cmd not in self.commands: die("Unknown command, %s", cmd) func = self.commands[cmd] func(repo, cmdline) sys.stdout.flush() return True
def main(args): """Starts a new remote helper for the specified repository. """ if len(args) != 3: die("Expecting exactly three arguments.") sys.exit(1) if os.getenv("GIT_DEBUG_TESTGIT"): import git_remote_helpers.util git_remote_helpers.util.DEBUG = True alias = sanitize(args[1]) url = sanitize(args[2]) if not alias.isalnum(): warn("non-alnum alias '%s'", alias) alias = "tmp" args[1] = alias args[2] = url repo = get_repo(alias, url) debug("Got arguments %s", args[1:]) more = True # Use binary mode since Python 3 does not permit unbuffered I/O in text # mode. Unbuffered I/O is required to avoid data that should be going # to git-fast-import after an "export" command getting caught in our # stdin buffer instead. sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) while (more): more = read_one_line(repo)
def main(self, args): """Starts a new remote helper for the specified repository. """ if len(args) != 3: die("Expecting exactly three arguments.") sys.exit(1) if os.getenv("GIT_REMOTE_HELPER_DEBUG"): import git_remote_helpers.util git_remote_helpers.util.DEBUG = True alias = self.sanitize(args[1]) url = self.sanitize(args[2]) if not alias.isalnum(): warn("non-alnum alias '%s'", alias) alias = "tmp" args[1] = alias args[2] = url repo = self.get_repo(alias, url) debug("Got arguments %s", args[1:]) more = True sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0) while (more): more = self.read_one_line(repo)
def read_one_line(repo): """Reads and processes one command. """ sleepy = os.environ.get("GIT_REMOTE_TESTGIT_SLEEPY") if sleepy: debug("Sleeping %d sec before readline" % int(sleepy)) time.sleep(int(sleepy)) line = sys.stdin.readline() cmdline = line if not cmdline: warn("Unexpected EOF") return False cmdline = cmdline.strip().split() if not cmdline: # Blank line means we're about to quit return False cmd = cmdline.pop(0) debug("Got command '%s' with args '%s'", cmd, ' '.join(cmdline)) if cmd not in COMMANDS: die("Unknown command, %s", cmd) func = COMMANDS[cmd] func(repo, cmdline) sys.stdout.flush() return True
def do_export(self, repo, args): """Imports a fast-import stream from git to testgit. """ if not repo.gitdir: die("Need gitdir to export") localrepo = self.update_local_repo(repo) refs_before = self.get_refs(repo, repo.gitdir) localrepo.importer.do_import(localrepo.gitdir) refs_after = self.get_refs(repo, repo.gitdir) changed = {} for name, value in refs_after.iteritems(): if refs_before.get(name) == value: continue changed[name] = value if not repo.local(): repo.non_local.push(repo.gitdir) for ref in changed: print "ok %s" % ref print
def parse_git_config (): """Return a dict containing the parsed version of 'git config -l'.""" exit_code, output, errors = run_command(("git", "config", "-z", "-l")) if exit_code: die("Failed to retrieve git configuration") assert not errors return dict([e.split('\n', 1) for e in output.split("\0") if e])
def main(self, args): """Starts a new remote helper for the specified repository. """ if len(args) != 3: die("Expecting exactly three arguments.") sys.exit(1) if os.getenv("GIT_REMOTE_HELPER_DEBUG"): import git_remote_helpers.util git_remote_helpers.util.DEBUG = True alias = self.sanitize(args[1]) url = self.sanitize(args[2]) if not alias.isalnum(): warn("non-alnum alias '%s'", alias) alias = "tmp" args[1] = alias args[2] = url repo = self.get_repo(alias, url) debug("Got arguments %s", args[1:]) more = True sys.stdin = os.fdopen(sys.stdin.fileno(), "r", 0) while more: more = self.read_one_line(repo)
def get_git_dir (): """Return the path to the GIT_DIR for this repo.""" args = ("git", "rev-parse", "--git-dir") exit_code, output, errors = run_command(args) if exit_code: die("Failed to retrieve git dir") assert not errors return output.strip()
def do_gitdir(repo, args): """Stores the location of the gitdir. """ if not args: die("gitdir needs an argument") repo.gitdir = ' '.join(args)
def write_marksfile(self, name): try: f = open(name, "w") for pair in sorted(self.idmap.iteritems()): f.write("%s %s\n" % pair) f.close() except IOError, e: die("write: %s", str(e))
def do_gitdir(repo, args): """ """ if not args: die("gitdir needs an argument") repo.gitdir = ' '.join(args)
def load_marksfile(self, name): try: f = open(name) lines = f.readlines() f.close() parsed = [i.strip().split(' ') for i in lines] self.idmap = dict((i[0], i[1]) for i in parsed) except IOError, e: die("load: %s", str(e))
def update(self, base): path = self.repo.get_base_path(base) if not os.path.exists(path): die("could not find repo at %s", path) repo = self.hg.repository(self.repo.ui, path) repo.ui.setconfig('ui', 'quiet', "true") repo.pull(self.repo, heads=self.repo.heads(), force=True)
def update(self, base): path = self.repo_path(base) if not os.path.exists(path): die("could not find repo at %s", path) repo = self.hg.repository(self.repo.ui, path) repo.ui.setconfig('ui', 'quiet', "true") repo.pull(self.repo, heads=self.repo.heads(), force=True)
def push(self, base): """Pushes from the non-local repo to base. """ path = os.path.join(self.repo.get_base_path(base), '.git') if not os.path.exists(path): die("could not find repo at %s", path) args = ["git", "--git-dir=" + path, "push", "--quiet", self.repo.gitpath] subprocess.check_call(args)
def push(self, base): path = self.repo.get_base_path(base) if not os.path.exists(path): die("could not find repo at %s", path) repo = self.hg.repository(self.repo.ui, path) self.repo.ui.setconfig("ui", "quiet", "true") repo.ui.setconfig("ui", "quiet", "true") repo.push(self.repo, force=False)
def push(self, base): path = self.repo.get_base_path(base) if not os.path.exists(path): die("could not find repo at %s", path) repo = self.hg.repository(self.repo.ui, path) self.repo.ui.setconfig('ui', 'quiet', "true") repo.ui.setconfig('ui', 'quiet', "true") repo.push(self.repo, force=False)
def do_import(repo, args): """Exports a fast-import stream from testgit for git to import. """ if len(args) != 1: die("Import needs exactly one ref") if not repo.gitdir: die("Need gitdir to import") repo = update_local_repo(repo) repo.exporter.export_repo(repo.gitdir)
def get_branch(ref): if not ref.startswith("refs/heads/"): die("Ref should start with 'refs/heads/'") splitref = ref.split('/') if len(splitref) != 3: die("Cannot parse ref, need 3 slashes") branch = splitref[2] return branch
def push(self, base): """Pushes from the non-local repo to base. """ path = os.path.join(self.repo.get_base_path(base), '.git') if not os.path.exists(path): die("could not find repo at %s", path) args = ["git", "--git-dir=" + path, "push", "--quiet", self.repo.gitpath] child = subprocess.Popen(args) if child.wait() != 0: raise CalledProcessError
def update(self, base): """Updates checkout of the non-local repo in base. """ path = os.path.join(self.repo.get_base_path(base), '.git') if not os.path.exists(path): die("could not find repo at %s", path) args = ["git", "--git-dir=" + path, "fetch", "--quiet", self.repo.gitpath] subprocess.check_call(args) args = ["git", "--git-dir=" + path, "update-ref", "refs/heads/master", "FETCH_HEAD"] subprocess.check_call(args)
def push(self, base): """Pushes from the non-local repo to base. """ path = os.path.join(self.repo.get_base_path(base), '.git') if not os.path.exists(path): die("could not find repo at %s", path) args = [ "git", "--git-dir=" + path, "push", "--quiet", self.repo.gitpath, "--all" ] child = check_call(args)
def do_import(repo, args): """Exports a fast-import stream from testgit for git to import. """ if len(args) != 1: die("Import needs exactly one ref") if not repo.gitdir: die("Need gitdir to import") ref = args[0] refs = [ref] while True: line = sys.stdin.readline().decode() if line == '\n': break if not line.startswith('import '): die("Expected import line.") # strip of leading 'import ' ref = line[7:].strip() refs.append(ref) print("feature done") if os.environ.get("GIT_REMOTE_TESTGIT_FAILURE"): die('Told to fail') repo = update_local_repo(repo) repo.exporter.export_repo(repo.gitdir, refs) print("done")
def do_export(repo, args): """Imports a fast-import stream from git to testgit. """ if not repo.gitdir: die("Need gitdir to export") update_local_repo(repo) changed = repo.importer.do_import(repo.gitdir) if not repo.local: repo.non_local.push(repo.gitdir) for ref in changed: print "ok %s" % ref print
def update(self, base): """Updates checkout of the non-local repo in base. """ path = os.path.join(self.repo.get_base_path(base), '.git') if not os.path.exists(path): die("could not find repo at %s", path) args = ["git", "--git-dir=" + path, "fetch", "--quiet", self.repo.gitpath] child = subprocess.Popen(args) if child.wait() != 0: raise CalledProcessError args = ["git", "--git-dir=" + path, "update-ref", "refs/heads/master", "FETCH_HEAD"] child = subprocess.Popen(args) if child.wait() != 0: raise CalledProcessError
def update(self, base): """Updates checkout of the non-local repo in base. """ path = os.path.join(self.repo.get_base_path(base), '.git') if not os.path.exists(path): die("could not find repo at %s", path) args = [ "git", "--git-dir=" + path, "fetch", "--quiet", self.repo.gitpath ] check_call(args) args = [ "git", "--git-dir=" + path, "update-ref", "refs/heads/master", "FETCH_HEAD" ] child = check_call(args)
def do_export(repo, args): """Imports a fast-import stream from git to testgit. """ if not repo.gitdir: die("Need gitdir to export") if os.environ.get("GIT_REMOTE_TESTGIT_FAILURE"): die('Told to fail') update_local_repo(repo) changed = repo.importer.do_import(repo.gitdir) if not repo.local: repo.non_local.push(repo.gitdir) for ref in changed: print("ok %s" % ref) print('')
def read_one_line(repo): line = sys.stdin.readline() cmdline = line.strip().split() if not cmdline: return False # Blank line means we're about to quit cmd = cmdline.pop(0) debug("Got command '%s' with args '%s'", cmd, ' '.join(cmdline)) if cmd not in COMMANDS: die("Unknown command, %s", cmd) func = COMMANDS[cmd] func(repo, cmdline) sys.stdout.flush() return True
def do_export(repo, args): """Imports a fast-import stream from git to testgit. """ if not repo.gitdir: die("Need gitdir to export") dirname = repo.get_base_path(repo.gitdir) if not os.path.exists(dirname): os.makedirs(dirname) path = os.path.join(dirname, 'testgit.marks') print path print path if os.path.exists(path) else "" sys.stdout.flush() update_local_repo(repo) repo.importer.do_import(repo.gitdir) repo.non_local.push(repo.gitdir)
def get_repo(self, alias, url): """Returns a hg.repository object initialized for usage. """ try: from mercurial import hg, ui except ImportError: die("Mercurial python libraries not installed") remote = False if url.startswith("remote://"): remote = True url = "file://%s" % url[9:] ui = ui.ui() source, revs, checkout = util.parseurl(ui.expandpath(url), ['default']) repo = hg.repository(ui, source) if repo.capable('branchmap'): revs += repo.branchmap().keys() revs = set(revs) prefix = 'refs/hg/%s/' % alias debug("prefix: '%s'", prefix) repo.marksfile = 'git.marks' repo.hg = hg repo.prefix = prefix repo.revs_ = revs # must not override repo.revs() self.setup_repo(repo, alias) repo.git_hg = GitHg(warn) repo.exporter = GitExporter(repo) repo.importer = GitImporter(repo) repo.non_local = NonLocalHg(repo) repo.is_local = not remote and repo.local() return repo
def do_import(self, repo, args): """Exports a fast-import stream from testgit for git to import. """ if len(args) != 1: die("Import needs exactly one ref") if not repo.gitdir: die("Need gitdir to import") ref = args[0] refs = [ref] while True: line = sys.stdin.readline() if line == "\n": break if not line.startswith("import "): die("Expected import line.") # strip of leading 'import ' ref = line[7:].strip() refs.append(ref) repo = self.update_local_repo(repo) repo.exporter.export_repo(repo.gitdir, refs) print "done"
def do_import(repo, args): """Exports a fast-import stream from testgit for git to import. """ if len(args) != 1: die("Import needs exactly one ref") if not repo.gitdir: die("Need gitdir to import") ref = args[0] refs = [ref] while True: line = sys.stdin.readline() if line == '\n': break if not line.startswith('import '): die("Expected import line.") # strip of leading 'import ' ref = line[7:].strip() refs.append(ref) repo = update_local_repo(repo) repo.exporter.export_repo(repo.gitdir, refs) print "done"
def do_import(repo, args): """ """ if len(args) != 1: die("Import needs exactly one ref") if not repo.gitdir: die("Need gitdir to import") if args[0] == 'HEAD': branch = 'tip' else: branch = get_branch(args[0]) repo = update_local_repo(repo) repo.exporter.setup(True, repo.gitdir, True, True) repo.exporter.export_repo() repo.exporter.export_branch('tip', 'tip') repo.exporter.write_marks(repo.gitdir)