Created
February 24, 2012 18:20
-
-
Save koshigoe/1902618 to your computer and use it in GitHub Desktop.
clone svn:externals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# | |
# Inspired by https://github.com/andrep/git-svn-clone-externals | |
# | |
# MIT License http://koshigoe.mit-license.org | |
# | |
require 'fileutils' | |
module Git | |
class Svn | |
CABINET = '.git_externals' | |
def initialize | |
@url ||= `git svn info | grep '^URL: ' | cut -d' ' -f2`.chomp | |
@cwd = File.expand_path '.' | |
unless system("grep -q '#{CABINET}/*' .git/info/exclude") | |
open('.git/info/exclude', 'a') do |output| | |
output.puts "\n#{CABINET}/*" | |
end | |
end | |
end | |
def clone_externals | |
each_externals do |property| | |
puts "clone: #{property[:path]}#{property[:name]}" | |
checkout_to = "#{CABINET}/#{property[:path]}#{property[:name]}" | |
link_to = "#{property[:path]}#{property[:name]}" | |
next if File.exists?(checkout_to) | |
begin | |
FileUtils.mkdir_p File.dirname(checkout_to) | |
if system("git svn clone #{revision(property[:source])} #{property[:source]} #{checkout_to}") | |
FileUtils.ln_s File.expand_path(checkout_to), link_to, :force => true | |
unless system("grep -q '#{link_to}' .git/info/exclude") | |
open('.git/info/exclude', 'a') do |output| | |
output.puts "\n#{link_to}" | |
end | |
end | |
end | |
rescue => e | |
$stderr.puts e.inspect | |
end | |
end | |
end | |
def rebase_externals | |
Dir["#{CABINET}/**/.git"].each do |path| | |
Dir.chdir(File.dirname(path)) do | |
puts "rebase: #{Dir.pwd}" | |
system("git svn rebase") | |
end | |
end | |
end | |
def fetch_externals | |
Dir["#{CABINET}/**/.git"].each do |path| | |
Dir.chdir(File.dirname(path)) do | |
puts "fetch: #{Dir.pwd}" | |
system("git svn fetch") | |
end | |
end | |
end | |
protected | |
def each_externals | |
@_cursor = nil | |
IO.popen('git svn show-externals') do |io| | |
while line = io.gets | |
line.chomp! | |
if %r{\A# /(.+)\z} =~ line | |
@_cursor = $1 | |
elsif @_cursor && line.size > 0 | |
yield parse_property(line) | |
end | |
end | |
end | |
end | |
def parse_property(line) | |
if %r|\A/#{@_cursor}([^\s]+) (.+)\z| =~ line | |
source, name = $1, $2 | |
source, name = name, source if name.include? '/' | |
if %r{\A(?:/|\.)} =~ source | |
path = File.expand_path("#{@_cursor}#{source}").sub("#{@cwd}/", '') | |
source = "#{@url}/#{path}" | |
end | |
{ | |
:path => @_cursor, | |
:source => source, | |
:name => name, | |
} | |
else | |
raise ArgumentError, "Invalid property: #{line}" | |
end | |
end | |
def revision(url) | |
'-' + `LANG=C svn log -l1 #{url}|awk '{if(NR==2){ print $1 }}'`.chomp | |
end | |
end | |
end | |
unless File.exists? '.git' | |
raise '.git not found.' | |
end | |
def help | |
$stderr.puts <<EOF | |
usage: git-svn-externals <subcommand> | |
Available subcommands: | |
clone | |
rebase | |
fetch | |
help | |
EOF | |
exit | |
end | |
case ARGV.first | |
when 'clone' | |
Git::Svn.new.clone_externals | |
when 'rebase' | |
Git::Svn.new.rebase_externals | |
when 'fetch' | |
Git::Svn.new.fetch_externals | |
when 'help' | |
help | |
else | |
help | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment