Skip to content

Instantly share code, notes, and snippets.

@minad
Created April 9, 2011 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save minad/911610 to your computer and use it in GitHub Desktop.
Save minad/911610 to your computer and use it in GitHub Desktop.
Create a mirror of all your github repositories
#!/usr/bin/env ruby
require 'shellwords'
require 'json'
if ARGV.length != 3
puts "Usage: #{$0} <user> <password> <directory>"
exit 1
end
user = ARGV[0]
password = ARGV[1]
Dir.chdir(ARGV[2])
repos = JSON.parse `curl -s -u #{Shellwords.shellescape user}:#{Shellwords.shellescape password} 'https://api.github.com/users/#{user}/repos?per_page=999&type=all'`
orgs = JSON.parse `curl -s -u #{Shellwords.shellescape user}:#{Shellwords.shellescape password} 'https://api.github.com/users/#{user}/orgs?per_page=999'`
orgs.each do |org|
puts "Organization #{org['login']}"
repos += JSON.parse `curl -s -u #{Shellwords.shellescape user}:#{Shellwords.shellescape password} 'https://api.github.com/orgs/#{org['login']}/repos?per_page=999&type=public'`
end
found = {}
repos.each do |repo|
name = repo['full_name'] + '.git'
if name =~ %r{\A#{user}/}
name = File.basename(name)
else
parent = File.dirname(name)
Dir.mkdir(parent) unless File.exists?(parent)
end
found[name] = true
if File.exists?(name)
puts "Fetching #{name}..."
Dir.chdir(name) do
`git fetch 2>&1`
end
else
puts "Cloning #{name}..."
`git clone --mirror #{repo['clone_url']} #{name} 2>&1`
end
File.open(File.join(name, 'description'), 'w') {|file| file.puts(repo['description']) }
end
Dir['**/*.git'].each do |name|
puts "Not a GitHub repository: #{name}" unless found[name]
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment