lib/svn2git/migration.rb in svn2git-1.3.3 vs lib/svn2git/migration.rb in svn2git-2.0.0

- old
+ new

@@ -8,18 +8,26 @@ attr_reader :dir def initialize(args) @options = parse(args) - show_help_message("Missing SVN_URL parameter") if args.empty? - show_help_message('Too many arguments') if args.size > 1 - - @url = args.first + if @options[:rebase] + show_help_message('Too many arguments') if args.size > 0 + verify_working_tree_is_clean + else + show_help_message('Missing SVN_URL parameter') if args.empty? + show_help_message('Too many arguments') if args.size > 1 + @url = args.first + end end def run! - clone! + if @options[:rebase] + get_branches + else + clone! + end fix_tags fix_branches fix_trunk optimize_repos end @@ -44,10 +52,14 @@ opts.banner = 'Usage: svn2git SVN_URL [options]' opts.separator '' opts.separator 'Specific options:' + opts.on('--rebase', 'Instead of cloning a new project, rebase an existing one against SVN') do + options[:rebase] = true + end + opts.on('--trunk TRUNK_PATH', 'Subpath to trunk from repository URL (default: trunk)') do |trunk| options[:trunk] = trunk end opts.on('--branches BRANCHES_PATH', 'Subpath to branches from repository URL (default: branches)') do |branches| @@ -148,12 +160,16 @@ get_branches end def get_branches - @local = run_command("git branch -l").split(/\n/).collect{ |b| b.strip } - @remote = run_command("git branch -r").split(/\n/).collect{ |b| b.strip } + # Get the list of local and remote branches, taking care to ignore console color codes and ignoring the + # '*' character used to indicate the currently selected branch. + @local = run_command("git branch -l --no-color").split(/\n/).collect{ |b| b.gsub(/\*/,'').strip } + @remote = run_command("git branch -r --no-color").split(/\n/).collect{ |b| b.gsub(/\*/,'').strip } + + # Tags are remote branches that start with "tags/". @tags = @remote.find_all { |b| b.strip =~ %r{^tags\/} } end def fix_tags @tags.each do |tag| @@ -171,24 +187,32 @@ def fix_branches svn_branches = @remote.find_all { |b| not @tags.include?(b) } svn_branches.each do |branch| branch = branch.strip - next if branch == 'trunk' + if @options[:rebase] && (@local.include?(branch) || branch == 'trunk') + branch = 'master' if branch == 'trunk' + run_command("git checkout -f #{branch}") + run_command("git svn rebase") + next + end + + next if branch == 'trunk' + run_command("git branch -t #{branch} remotes/#{branch}") run_command("git checkout #{branch}") - run_command("git checkout -b #{branch}") end end def fix_trunk trunk = @remote.find { |b| b.strip == 'trunk' } - if trunk + if trunk && ! @options[:rebase] run_command("git checkout trunk") run_command("git branch -D master") run_command("git checkout -f -b master") - run_command("git branch -d -r trunk") + else + run_command("git checkout -f master") end end def optimize_repos run_command("git gc") @@ -215,9 +239,17 @@ def show_help_message(msg) puts "Error starting script: #{msg}\n\n" puts @opts.help exit + end + + def verify_working_tree_is_clean + status = run_command('git status --porcelain --untracked-files=no') + unless status.strip == '' + puts 'You have local pending changes. The working tree must be clean in order to continue.' + exit + end end def escape_quotes(str) str.gsub("'", "'\\\\''") end