Skip to content

Instantly share code, notes, and snippets.

@steveh
Created October 13, 2011 01:26
Show Gist options
  • Select an option

  • Save steveh/1283104 to your computer and use it in GitHub Desktop.

Select an option

Save steveh/1283104 to your computer and use it in GitHub Desktop.
Git Megaclone
source :rubygems
gem "excon"
gem "json"
GEM
remote: http://rubygems.org/
specs:
excon (0.7.6)
json (1.6.1)
PLATFORMS
ruby
DEPENDENCIES
excon
json
#!/usr/bin/env ruby
username = "CHANGEME"
password = "CHANGEME"
base = "/path/to/CHANGEME"
# M E G A C L O N E
require "base64"
require "excon"
require "json"
require "pp"
require "pathname"
class Github
ENDPOINT = "https://api.github.com"
PER_PAGE = 100
def initialize(username, password)
@username = username
@password = password
encoded = Base64.encode64("#{username}:#{password}").chomp
@basic = { "Authorization" => "Basic #{encoded}" }
@github = Excon.new(ENDPOINT)
end
def orgs
request_with_pagination(:path => "/user/orgs")
end
def user_repos
request_with_pagination(:path => "/user/repos")
end
def org_repos(org)
request_with_pagination(:path => "/orgs/#{org["login"]}/repos")
end
def user_and_org_repos
user_repos + orgs.collect{ |org| org_repos(org) }.flatten
end
private
def request_with_pagination(options = {})
page = 1
result = []
count = 0
begin
response = @github.request({ :method => "GET", :query => { :page => page, :per_page => PER_PAGE }, :headers => @basic }.merge(options))
if response.status == 200
json = JSON.parse(response.body)
count = json.count
result += json
page += 1
else
raise "Failed to fetch #{options[:path]}"
end
count = 0 if count < PER_PAGE
end while count > 0
result
end
end
github = Github.new(username, password)
repos = github.user_and_org_repos
basepath = Pathname.new(base)
repos.each do |repo|
ownerpath = basepath + repo["owner"]["login"]
ownerpath.mkpath unless ownerpath.exist?
repodirname = "#{repo["name"]}.git"
repopath = ownerpath + repodirname
puts repo["html_url"]
if repopath.exist?
Dir.chdir(repopath.to_s) do
`git remote update`
end
else
Dir.chdir(ownerpath.to_s) do
`git clone --mirror #{repo["ssh_url"]} #{repodirname}`
end
end
end
`chown -R gitosis:gitosis #{base}`
`find #{base} -type d -exec chmod 755 {} \\;`
`find #{base} -type f -exec chmod 644 {} \\;`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment