Hi folks.

Today’s is a quick tip for keeping your forks updated.

If you are like me, and have at least a 100 forks in your repository because: * You would like to contribute at some point * Save it for yourself because you are afraid that it disappears * Would like to make modifications for your own benefit * Whatever the reason

…then you probably have a lot of trouble keeping them updated and making sure you always see the latest change.

Upstream can change a lot especially if it’s a busy repository.

Fret not. Help is here. This little ruby script will solve your troubles:

#!/usr/bin/env ruby require 'octokit' require 'logger' @logger = Logger . new ( "output.log" ) def update_fork ( repo ) repo_name = repo . name # clone the repository -- octokit doesn't provide this feature as it's a github api library @logger . info ( "cloning into #{ repo . ssh_url } " ) system ( "git clone #{ repo . ssh_url } #{ repo_name } " ) # setup upstream for updating @logger . info ( "setup upstream to #{ repo . parent . ssh_url } " ) system ( "cd #{ repo_name } && git remote add upstream #{ repo . parent . ssh_url } " ) # do the update @logger . info ( "doing the update with push" ) system ( "cd #{ repo_name } && git fetch upstream && git rebase upstream/master && git push origin" ) ensure # ensure that the folder is cleaned up @logger . info ( "cleanup: removing the repository folder" ) system ( "rm -fr #{ repo_name } " ) end client = Octokit :: Client . new ( :access_token => ENV [ 'GIT_TOKEN' ] , per_page : 100 ) repos = client . repos ({}, query : { type : 'owner' , sort : 'asc' }) # Go through all the pages and add them to the list of repositories. repos . concat ( client . last_response . rels [ :next ]. get . data ) repos = repos . select { | r | r . fork } @logger . info ( "going to update ' #{ repos . length } ' repositories" ) repos . each do | repo | # get the repositories information @logger . info ( "updating #{ repo . name } " ) r = client . repository ( repo . id ) update_fork ( r ) end

This script is also available as a Gist located here.

Put this into a cron job, or a Jenkins job on a schedule and you should be good to go.

Note two things: First: ENV['GIT_TOKEN'] this should be set to a token which you can acquire by navigating to tokens. Add a token which has repo access.

Second: Obviously this script will push to your local repository. So wherever you run this, make sure git is set-up and can push to your repository via SSH. This script is using ssh_url for the repositories. It won’t ask for a username or a password.

That’s it. Enjoy and keep updating.

Thanks for reading

Gergely.