Skip to content

Instantly share code, notes, and snippets.

@erikvanzijst
Last active July 1, 2020 18:56
Show Gist options
  • Save erikvanzijst/2170ab3e3ac2b8160b5b7ffd9a322268 to your computer and use it in GitHub Desktop.
Save erikvanzijst/2170ab3e3ac2b8160b5b7ffd9a322268 to your computer and use it in GitHub Desktop.
Clone all Bitbucket Mercurial repos
#!/usr/bin/env python3
import argparse
import os
import subprocess
# install deps:
# $ pip install requests mercurial
import requests
# Create an OAuth Consumer with Account and Repository Read permission:
# https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html
parser = argparse.ArgumentParser()
parser.add_argument('-k', '--key', type=str, required=True, help="the OAuth consumer key (e.g. pu5HwV2FKaU7JTkqRW)")
parser.add_argument('-s', '--secret', type=str, required=True,
help="the OAuth consumer secret (e.g. gAgtajY8RjBZc6rpxNbFuNhLj5x8JJnE)")
parser.add_argument("dest_dir", default=os.getcwd(), type=str, nargs='?',
help="directory to clone repositories under")
args = parser.parse_args()
os.path.exists(args.dest_dir) or os.makedirs(args.dest_dir)
with requests.Session() as session:
resp = session.post("https://bitbucket.org/site/oauth2/access_token", data={"grant_type": "client_credentials"},
auth=(args.key, args.secret))
resp.raise_for_status()
token = resp.json()['access_token']
session.headers["Authorization"] = "Bearer " + token
url = ("https://api.bitbucket.org/2.0/repositories/" +
session.get("https://api.bitbucket.org/2.0/user").json()['username'] +
"?q=scm=%22hg%22&fields=values.links,values.slug,next,values.full_name")
while url:
resp = session.get(url)
resp.raise_for_status()
data = resp.json()
for repo in data['values']:
print("\nCloning " + repo['links']['html']['href'])
subprocess.call(['hg', 'clone', 'https://x-token-auth:%[email protected]/%s' % (token, repo['full_name']),
os.path.join(args.dest_dir, repo['slug'])])
url = data.get("next")
@erikvanzijst
Copy link
Author

erikvanzijst commented May 14, 2020

Quick and dirty way to clone all your Mercurial repos from Bitbucket before they get deleted: https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket

Create an OAuth Consumer with account and repository read access on your Bitbucket account: https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html
Tick the "private consumer" box and fill out a callback URL (actual value irrelevant).

clone_hg

$ virtualenv -p `which python3` env
$ source env/bin/activate
(env) $ pip install requests mercurial
(env) $ python ./cloneall.py --key BVZUkskLCby8zTxk5Y --secret KDD4m4Mj95J4ULrHgV75p6Hf4fut7NvG repos

@dholth
Copy link

dholth commented May 14, 2020

Partial: using hg-git to automatically convert to git 😢 and send to gitlab, or github with the gh client...

            # convert it
            gitname = basename + ".git"
            gitpath = Path(gitname)
            if not gitpath.exists():
                subprocess.check_call(["git", "init", "--bare", str(gitpath)])
                subprocess.check_call(
                    [HG, "bookmark", "-r", "default", "master"], cwd=basename
                )

            # this will complain, but will it work anyway?
            subprocess.call([HG, "push", f"../{gitpath}"], cwd=basename)

            labname = remotename(gitname)
            subprocess.call(["gh", "repo", "create", basename, "--public"], cwd=gitname)
            subprocess.check_call(["git", "push", "--mirror", labname], cwd=gitname)

@cheater
Copy link

cheater commented Jun 29, 2020

you're reeeaaally missing a shebang at the top of the file >_>

@erikvanzijst
Copy link
Author

Not anymore! :-D

@cheater
Copy link

cheater commented Jul 1, 2020

😢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment