"""hggithub Add some usefull command to work with github """ import os import os.path as osp from shutil import move from mercurial import registrar, error from mercurial.i18n import _ from subprocess import check_output, CalledProcessError, STDOUT cmdtable = {} command = registrar.command(cmdtable) def cmd(description, *args, **kwargs): print(description) if "quiet" in kwargs: quiet = kwargs.pop("quiet") try: kwargs["stderr"] = STDOUT check_output(*args, **kwargs) except CalledProcessError as ex: if not quiet: print(ex.output).strip() print("Command exited with code %d" % ex.returncode) raise def git_clone(path_url, destination): cmd( "Cloning Git fork repository", ["git", "clone", path_url, destination, "--bare"] ) def git_configure_upstream(git_repo, git_upstream_url): cmd( "Adding upstream remote", ["git", "remote", "add", "upstream", git_upstream_url], cwd=git_repo, ) git_pull_master(git_repo) def git_pull_master(git_repo): cmd( "Fetching upstream remote", ["git", "fetch", "upstream", "master:master"], cwd=git_repo, ) cmd( "Pushing master branch to Git fork repository", ["git", "push", "-f", "origin", "master"], cwd=git_repo, ) def hg_clone(path, destination): cmd( "Creating Mercurial repository", ["hg", "clone", "--config", "phases.new-commit=draft", path, destination], ) cmd("Publishing master bookmark", ["hg", "phase", "-p", "master"], cwd=destination) def update_hgrc(hg_repo): hgrc_path = osp.join(hg_repo, ".hg", "hgrc") with open(hgrc_path, "w+") as fobj: fobj.write( """\ [paths] default = .hg/git.git [gitrepo] gitrepo = .hg/git.git """ ) def hg_pull(): cmd( "Updating Mercurial repository", ["hg", "--config", "phases.new-commit=draft", "pull"], ) cmd("Publishing master bookmark", ["hg", "phase", "-p", "master"]) def _ghclone(git_fork_url, git_upstream_url, destination): working_dir, project_name = osp.split(destination) git_repo = osp.abspath(osp.join(working_dir, ".%s.git" % project_name)) if osp.isdir(destination): raise ValueError( "Destination directory {} for hg repository should not exist".format( destination ) ) git_clone(git_fork_url, git_repo) git_configure_upstream(git_repo, git_upstream_url) hg_clone(git_repo, destination) final_git_repo = osp.abspath(osp.join(destination, ".hg", "git.git")) move(git_repo, final_git_repo) update_hgrc(destination) def _ghpull(git_repo): branches = check_output( ["git", "branch", "--format=%(refname:lstrip=2)"], cwd=git_repo ) git_pull_master(git_repo) for branch in branches.splitlines(): if branch != "master": try: cmd( "Fetching branch %s from remote Git fork repository" % branch, ["git", "fetch", "origin", "%s:%s" % (branch, branch)], cwd=git_repo, quiet=True, ) except CalledProcessError: print("Couldn't fetch remote branch, ignoring") hg_pull() def _ghpush(git_repo, bookmark): if bookmark == "master": raise ValueError("Cannot push master branch") cmd( "Pushing bookmark to local Git repository", ["hg", "push", "-B", bookmark, "-f"], ) # TODO use --force-with-lease if possible cmd( "Pushing Git branch to Git fork repository", ["git", "push", "--set-upstream", "origin", bookmark, "-f"], cwd=git_repo, ) def _ghremote(git_repo, git_remote_url, git_branch, hg_bookmark): if hg_bookmark == "master": raise ValueError("Cannot replace master bookmark") cmd( "Fetching branch %s to %s from specified remote Git repository" % (git_branch, hg_bookmark), ["git", "fetch", git_remote_url, "%s:%s" % (git_branch, hg_bookmark)], cwd=git_repo, ) hg_pull() @command( "ghclone", [], _("git_fork_path git_upstream_path working_directory"), norepo=True ) def ghclone(ui, git_fork_url, git_upstream_url, working_directory, **opts): """Prepare working directory to work with github""" try: _ghclone(git_fork_url, git_upstream_url, working_directory) except CalledProcessError: pass except ValueError as ex: print(ex) @command("ghpull", [], _("")) def ghpull(ui, repo, **opts): os.chdir(repo.root) """Prepare working directory to work with github""" git_repo = ui.config("gitrepo", "gitrepo") try: _ghpull(git_repo) except CalledProcessError: pass @command("ghpush", [], _("bookmark")) def ghpush(ui, repo, bookmark, **opts): """Prepare working directory to work with github""" os.chdir(repo.root) git_repo = ui.config("gitrepo", "gitrepo") try: _ghpush(git_repo, bookmark) except CalledProcessError: pass except ValueError as ex: print(ex) @command("ghremote", [], _("git_remote_path git_branch hg_bookmark")) def ghremote(ui, repo, git_remote_url, git_branch, hg_bookmark, **opts): """Pull remote branch from alternate Git repository""" os.chdir(repo.root) git_repo = ui.config("gitrepo", "gitrepo") try: _ghremote(git_repo, git_remote_url, git_branch, hg_bookmark) except CalledProcessError: pass