Introduction

I work with a large number of repositories, mostly on GitHub, some are my own but most are for work, and the volume only grows since we complete a lot of projects each year.

I find it useful to be able to clone everything I need in a number of scenarios.

Previously I wrote a clone tool for Stash (now BitBucket) called Stash Clone Tool.

Now, I present - Hub Clone Tool: A tool which clones all repositories a user has access to from GitHub.

Motivation

Personally I like to have a copy of code available so that it is there if I need it, for example for looking at an issue. In the past I travelled quite a lot, so having code available offline was important.

When setting up a new computer it can also be useful and help to quickly get back to a more normal state where your system is ready to use.

Like me, my team may not keep up with all the code and all the projects in development, so it can be as useful to them as it is for me.

A cursory search suggested there was little available to do this, and so I built my own little tool.

I hope others find it as useful as I do.

Getting Started

Hub Clone Tool is written in TypeScript and published on npm, so the easiest way to run it is via npx, which automatically downloads and execute binaries from npm packages:

npx hub-clone-tool

Alternatively it can be installed globally:

npm i -g hub-clone-tool

If installed locally it can then be run with hub-clone-tool or the hct alias.

I run it every few weeks, or if I created a new repo on one machine that I want on another, but even then I personally just run it via npx.

After checking the config looks right it fetches user repos, orgs and org repos where permissions allow using @octokit/rest.

All of this data feeds into a summary about the total number of repos to clone.

The tool then pauses to let the user continue or not.

The cloning process is kicked off using listr, simple-git, promises and a bit of glue to provide a view of progress that shows which tasks have been completed, skipped or are in progress. The git clone output is also visible under each active task.

If the destination path exists the cloning is skipped entirely, even if the target is not up-to-date (a potential future enhancement).

Configuration

For simplicity and speed of development I opted to use a Personal access token for authentication and store it in git's built in key-value configuration mechanism, storing it under the global config and reading it back using parse-git-config.

To generate a token go to github.com/settings/tokens and create a personal access token with the following scopes:

  • repo
  • read:org
Personal access tokens

Store the generated token:

git config --global --add github.apikey [token here]

We can see it added to ~/.gitconfig below:

❯ cat ~/.gitconfig 
[github]
	apikey = [secret]

Root Code Folder

By default the tool works out of the current working directory.

To ensure you always sync to the same folder, regardless of where you run the command, it is advised to set a code.home global git config variable:

git config --global --add code.home /home/paul/Documents/Code

❯ cat ~/.gitconfig 
[github]
	apikey = [secret]
[code]
	home = /home/paul/Documents/Code

A Quick GIF Demo

❯ npx hub-clone-tool

Conclusion

That's about all - I'm happy with it as a little tool. The code is a bit scrappy and it could do with tests, but equally it's quite simple. I am particularly happy with the output, it took some time to figure out the best way to do that, and it's not perfect - information can get lost when you have a lot of repos.

The source can be found on github: paul-ridgway/hub-clone-tool, any fixes, improvements or contributions are welcome!