Skip to content

Instantly share code, notes, and snippets.

@esotericenderman
Forked from SpotlightKid/clone-gists.py
Last active February 8, 2025 16:16
Show Gist options
  • Save esotericenderman/2af36266b30bb82b836be9446f1d76e0 to your computer and use it in GitHub Desktop.
Save esotericenderman/2af36266b30bb82b836be9446f1d76e0 to your computer and use it in GitHub Desktop.
Clone all gists of GitHub username given on the command line.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import sys
from os.path import exists, join
from subprocess import CalledProcessError, check_call
import requests
"""
Clones all gists of GitHub username given on the command line.
Forked from: https://gist.github.com/SpotlightKid/042491a9a2987af04a5a
Clones all gist repositories into a directory with the same name as the given username, within the current directory, using the gist ID as the directory name. If the directory already exists as a git repository, tries to perform a 'git pull' in it.
"""
def main(args=None):
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("-p", "--page", type=int, metavar="PAGE", help="Fetch only page PAGE from list of gists.")
ap.add_argument("--per-page", type=int, metavar="PER_PAGE", default=100, help="Fetch PER_PAGE gists per page.")
ap.add_argument("-s", "--ssh-url", action="store_true", help="Clone gists using SSH URL instead of HTTPS.")
ap.add_argument("-v", "--verbose", action="store_true", help="Run git commands with verbose messages (more logging).")
ap.add_argument("username", help="GitHub username.")
ap.add_argument("token", nargs="?", help="GitHub authentication token.")
args = ap.parse_args(args)
username = args.username
page = args.page
per_page = args.per_page
while True:
if page is None:
page = 1
print(f"Fetching page {page} of list of Gists of user {username}...")
url = "https://api.github.com/users/{}/gists".format(username)
headers = {"Authorization": "token " + args.token} if args.token else {}
resp = requests.get(url, headers=headers, params={"per_page": per_page, "page": page})
if resp.status_code == 200:
for gist in resp.json():
gist_id = gist["id"]
try:
if exists(join(username, gist_id, ".git")):
print(f"Updating gist {gist_id} via 'git pull'...")
check_call(["git", "pull", "-v" if args.verbose else "-q"], cwd=f"{username}/{gist_id}")
else:
url = gist["git_pull_url"]
if args.ssh_url:
url = url.replace("https://gist.github.com/", "git@gist.github.com:")
print(f"Cloning Gist from {url}...")
check_call(["git", "clone", "-v" if args.verbose else "-q", url, f"{args.username}/{gist_id}"])
except CalledProcessError:
print(f"*** ERROR cloning/updating gist {gist_id}. Please check output.")
except KeyboardInterrupt:
break
if 'rel="next"' in resp.headers.get("link", ""):
page += 1
else:
break
else:
return "Error reponse: {}".format(req.json().get("message"))
if args.page:
break
if __name__ == "__main__":
sys.exit(main() or 0)
#!/bin/bash
# Replaces gist git repository remote origin HTTPS URL with an SSH one.
if [[ "$1" = "-p" ]]; then
pull=1
shift
fi
for d in *; do
if [ -d "$d/.git" ]; then
pushd "$d"
url="$(git remote get-url origin)"
newurl="$(echo $url | sed -e 's|https://|git@|;s|\.com/|.com:|')"
if [ "x$url" != "x$newurl" ]; then
git remote set-url origin "$newurl"
fi
branch="$(git branch --show-current)"
tracking="$(git config branch.$branch.merge)"
if [ -z "$tracking" ]; then
git branch --set-upstream-to=origin/$branch $branch
fi
if [[ "$pull" -eq 1 ]]; then
git pull
fi
popd
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment