FWIW, I've written a little ruby script to help me manage/automate the process of applying patches across from my github mirrors to SVN. I'll attach it here in case anyone is interested.

I know, I could use git svn dcommit...but I've run into so many problems trying to initialize a git repo clone against the SVN repository, that I find that approach almost unusable. At least once I've managed to get my IP address banned for DOSing the svn server. :-)

Anyway, this is something I've started using; maybe it'll be useful to others.

-john

--
John Casey
Developer, PMC Chair - Apache Maven (http://maven.apache.org)
Blog: http://www.johnofalltrades.name/
#!/usr/bin/env ruby

require 'optparse'
require 'tempfile'

class Git2SvnPatcher
  
  def initialize( args=[] )
    @options = {}
    OptionParser.new {|opts|
      opts.on( '-i', "--input=DIR", "Git source directory" ){|dir| @options[:source] = dir}
      opts.on( '-o', "--output=DIR", "SVN target directory" ){|dir| @options[:target] = dir}
      opts.on( '-s', "--subject=SUBJECT", "JIRA issue ID (optional)"){|subject| @options[:subject] = subject}
      opts.on( '-N', "--number=NUM", "Number of commits format as patches (using git format-patch HEAD~N)"){|n| @options[:format_number]=n}
      opts.on( '-D', "--dry-run", "Simulated run (without committing anything!)" ){@options[:dry_run]=true}
      
      opts.on( '-h', "--help", "Print this help message and exit"){
        usage(opts)
        exit 0
      }
      
      opts.parse!(args)
      
      if ( !@options[:source] || !@options[:target] )
        puts "You must specified both input AND output directories!"
        usage(opts)
        exit 1
      end
    }
  end #init
  
  def usage(opts)
    puts opts.to_s
    puts
  end #usage
  
  def apply
    if ( @options[:format_number] )
      puts "Generating patch files from latest #{@options[:format_number]} commits in #{@options[:source]}..."
      Dir.chdir( @options[:source] ){
        exec( "git format-patch HEAD~#{@options[:format_number]}" )
      }
    end
    
    Dir.chdir( @options[:target] ) {
      Dir.glob( File.join( @options[:source], "00*.patch" ) ).each {|f|
        message = ""
        message << "[#{@options[:subject]}] " if @options[:subject]
        
        in_subject = false
        File.open( f ) {|file|
          file.each_line {|l|
            line = l.chomp
            if ( line =~ /Subject: \[PATCH \d+\/\d+\] (.+)/ )
              message << $1
              in_subject = true
            elsif ( in_subject )
              if ( line.length < 1 )
                in_subject = false
                break
              else
                part = line[1..-1]
                message << " " << part
              end
            end
          }
        }
        
        puts "\n\nFound patch: #{File.basename(f)}.\nMessage:\n\n\t#{message}\n\n"
        puts "Patch command:\n\tpatch -p1 < #{f}"
        if ( !prompt( "Apply this patch [Y/n]?", true) )
          exit 2
        end
        
        puts "patch -p1 < #{f}"
        exec( "patch -p1 < #{f}" )
        
        `svn status | grep '^?' | awk '{print $2}'`.each_line {|line|
          path = line.chomp
          exec( "svn add #{path}" )
        }
        
        puts "Accounting for files removed from SVN:"
        `svn status | grep '!' | awk '{print $2}'`.each_line {|line|
          path = line.chomp
          exec( "svn rm --force #{path}" )
        }
        
        puts "\n\n\n\n\nCurrent SVN status:"
        exec( "svn status" )
        puts "\n\n"
        
        message_file = Tempfile.new( "svn-commit" )
        message_file << message
        message_file.flush
        
        message_file_path = message_file.path
        puts "SVN commit command:\n\nsvn ci -F #{message_file_path}\nMessage file contents:\n\n#{File.read(message_file_path)}\n\n"
        if ( !prompt( "Commit this patch [y/N]?", false ) )
          exit 3
        end
        
        puts "svn ci -F '#{message_file_path}'"
        exec( "svn ci -F '#{message_file_path}'" ) unless @options[:dry_run]
      }
    }
    
    if ( @options[:format_number] )
      puts "Cleaning up generated patch files in #{@options[:source]}..."
      Dir.chdir( @options[:source] ){
        exec( "rm -v 00*.patch" )
      }
    end
    
  end
  
  def exec( command )
    system( command )
    ret = $?
    exit ret unless ret == 0
  end
  
  def prompt( message, default=nil )
    response = nil
    begin
      STDOUT.print message
      response = STDIN.gets.chomp
      if ( default != nil && ( !response || response.length < 1 ) )
        response = default
        break
      elsif ( response =~ /(([Tt][Rr][Uu][Ee])|([Yy]([Ee][Ss])?))/ )
        response = true
      elsif ( response =~ /(([Ff][Aa][Ls][Ss][Ee])|([Nn]([Oo])?))/ )
        response = false
      else
        puts "Invalid response."
        response = nil
      end
    end while response == nil
    
    response
  end
  
end #class

Git2SvnPatcher.new(ARGV).apply
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
For additional commands, e-mail: dev-h...@maven.apache.org

Reply via email to