Skip to content

Instantly share code, notes, and snippets.

Last active March 1, 2024 06:07
Show Gist options
  • Save mbostock/3883098 to your computer and use it in GitHub Desktop.
Save mbostock/3883098 to your computer and use it in GitHub Desktop.
The Gist to Clone All Gists
license: gpl-3.0

Run like so:

chmod u+x gist-clone-all
./gist-clone-all username OAUTH_TOKEN

You'll want to replace “username” with your own username and “OAUTH_TOKEN” with an OAuth token.

This script clones using the push URL, so you should probably be the owner of the gists. You could also use this to clone someone else's gists, but in that case you may wish to edit the code to use gist_pull_url instead.

#!/usr/bin/env node
var fs = require("fs"),
https = require("https"),
exec = require("child_process").exec;
// TODO --pull or --push
var user = process.argv[2],
token = process.argv[3];
fetchAndClone(1, function callback(error, nextPage) {
if (error) throw error;
if (nextPage > 0) fetchAndClone(nextPage, callback);
function fetchAndClone(page, callback) {
fetch(page, function(error, gists) {
if (error) return callback(error);
if (gists.length) ++page; else page = -1;
function cloneNext(gist) {
if (!gist) return callback(null, page);
if (directoryExists( return cloneNext(gists.pop());
console.log("cloning " +;
exec("git clone" + + ".git", function(error, stdout, stderr) {
if (error) return callback(error);
function fetch(page, callback) {
var request = https.request({
hostname: "",
port: 443,
path: "/users/" + encodeURIComponent(user) + "/gists?page=" + page,
method: "GET",
headers: {
"Accept": "application/vnd.github.v3+json",
"Authorization": "token " + token,
"User-Agent": "mbostock/gist-clone-all"
}, function(response) {
var chunks = [];
response.on("data", function(chunk) { chunks.push(chunk); });
response.on("end", function() { callback(null, JSON.parse(chunks.join(""))); });
request.on("error", callback);
function directoryExists(path) {
try {
return fs.lstatSync(path).isDirectory();
} catch (ignored) {
return false;
for i in *; do
if [ -d $i ]; then
pushd $i
git commit -am '' --allow-empty-message && git push
Copy link

tianchaijz commented May 10, 2016

Copy link

vetras commented May 18, 2016

The error:

root@dev-node:~/git# node gist-clone-all

TypeError: Object # has no method 'pop'

Is due to a invalid token.
If you add a log to the GIST object:


It comes with the GitHub message:

{ message: 'Bad credentials',
documentation_url: ''

My solution was to generate another token with more permissions.

Great stuff, many thanks!

Copy link

hyang0 commented Sep 2, 2016

I tried. It works. The environment is ubuntu 16.04 64bit.

First of all, you should install nodejs.

➜ curl -sL | sudo -E bash -

Installing the NodeSource Node.js v4.x LTS Argon repo...

➜ sudo apt-get install nodejs
Reading package lists... Done

Then you should generate a ssh public key and add it to you github account.

➜ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hyang0/.ssh/id_rsa):

Finnally, retry the script to sync your gists.

➜ ./ GIST-ACCOUNT Personal-access-token
cloning 7d5e4348f307f7cb2fbe
cloning 6986436
cloning 8572463
cloning 8572515
cloning 8572569
cloning a59175560823bd3cf383
cloning 5234efc9170aa3302dd9
cloning 75c39d5a6186e5bae304
cloning 159e719feb8b230a63fa
cloning 1eeb1affd91e91ba73c7
cloning 2498e1494bf7af5503b9

Cool job. Thanks!

Copy link

lmj0011 commented Dec 30, 2016

I only had to set the gist permission for the OAuth token, but you may not even need that set.

Would be nice to have, which permission should be set for the OAuth token, in the .

Copy link

lmj0011 commented Dec 30, 2016

I only had to set the gist permission for the OAuth token, but you may not even need that set.

correction: Only the "gist" scope is needed for the OAuth token.

Copy link

what is gist_pull_url?

Copy link

nlevick commented Mar 30, 2017

Great work! Thank you!

Copy link

I've been using but I was wondering if there was a way to clone all other people's forks of my gists, too, so I can easily see what changes have been made. I've been adding them manually with username as remote name.

Copy link

erbanku commented Mar 30, 2022

I have failed many times with this. but after searching the internet I found an easy one to do the same job, ghcloneall 1.10.1, enjoy!

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