lib/svn2git/migration.rb in svn2git-2.0.0 vs lib/svn2git/migration.rb in svn2git-2.1.0
- old
+ new
@@ -34,15 +34,19 @@
def parse(args)
# Set up reasonable defaults for options.
options = {}
options[:verbose] = false
+ options[:metadata] = false
+ options[:nominimizeurl] = false
options[:rootistrunk] = false
options[:trunk] = 'trunk'
options[:branches] = 'branches'
options[:tags] = 'tags'
options[:exclude] = []
+ options[:revision] = nil
+ options[:username] = nil
if File.exists?(File.expand_path(DEFAULT_AUTHORS_FILE))
options[:authors] = DEFAULT_AUTHORS_FILE
end
@@ -56,17 +60,22 @@
opts.on('--rebase', 'Instead of cloning a new project, rebase an existing one against SVN') do
options[:rebase] = true
end
+ opts.on('--username NAME', 'Username for transports that needs it (http(s), svn)') do |username|
+ options[:username] = username
+ 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|
options[:branches] = branches
end
+
opts.on('--tags TAGS_PATH', 'Subpath to tags from repository URL (default: tags)') do |tags|
options[:tags] = tags
end
opts.on('--rootistrunk', 'Use this if the root level of the repo is equivalent to the trunk and there are no tags or branches') do
@@ -86,10 +95,22 @@
opts.on('--notags', 'Do not try to import any tags') do
options[:tags] = nil
end
+ opts.on('--no-minimize-url', 'Accept URLs as-is without attempting to connect to a higher level directory') do
+ options[:nominimizeurl] = true
+ end
+
+ opts.on('--revision REV', 'Start importing from SVN revision') do |revision|
+ options[:revision] = revision
+ end
+
+ opts.on('-m', '--metadata', 'Include metadata in git logs (git-svn-id)') do
+ options[:metadata] = true
+ end
+
opts.on('--authors AUTHORS_FILE', "Path to file containing svn-to-git authors mapping (default: #{DEFAULT_AUTHORS_FILE})") do |authors|
options[:authors] = authors
end
opts.on('--exclude REGEX', 'Specify a Perl regular expression to filter paths when fetching; can be used multiple times') do |regex|
@@ -118,22 +139,38 @@
def clone!
trunk = @options[:trunk]
branches = @options[:branches]
tags = @options[:tags]
+ metadata = @options[:metadata]
+ nominimizeurl = @options[:nominimizeurl]
rootistrunk = @options[:rootistrunk]
authors = @options[:authors]
exclude = @options[:exclude]
+ revision = @options[:revision]
+ username = @options[:username]
if rootistrunk
# Non-standard repository layout. The repository root is effectively 'trunk.'
- run_command("git svn init --no-metadata --trunk=#{@url}")
+ cmd = "git svn init --prefix=svn/ "
+ cmd += "--username=#{username} " unless username.nil?
+ cmd += "--no-metadata " unless metadata
+ if nominimizeurl
+ cmd += "--no-minimize-url "
+ end
+ cmd += "--trunk=#{@url}"
+ run_command(cmd)
else
- cmd = "git svn init --no-metadata "
+ cmd = "git svn init --prefix=svn/ "
# Add each component to the command that was passed as an argument.
+ cmd += "--username=#{username} " unless username.nil?
+ cmd += "--no-metadata " unless metadata
+ if nominimizeurl
+ cmd += "--no-minimize-url "
+ end
cmd += "--trunk=#{trunk} " unless trunk.nil?
cmd += "--tags=#{tags} " unless tags.nil?
cmd += "--branches=#{branches} " unless branches.nil?
cmd += @url
@@ -141,22 +178,23 @@
run_command(cmd)
end
run_command("git config svn.authorsfile #{authors}") unless authors.nil?
- cmd = "git svn fetch"
+ cmd = "git svn fetch "
+ cmd += "-r #{revision}:HEAD " unless revision.nil?
unless exclude.empty?
# Add exclude paths to the command line; some versions of git support
# this for fetch only, later also for init.
regex = []
unless rootistrunk
regex << "#{trunk}[/]" unless trunk.nil?
regex << "#{tags}[/][^/]+[/]" unless tags.nil?
regex << "#{branches}[/][^/]+[/]" unless branches.nil?
end
regex = '^(?:' + regex.join('|') + ')(?:' + exclude.join('|') + ')'
- cmd += " '--ignore-paths=#{regex}'"
+ cmd += "'--ignore-paths=#{regex}'"
end
run_command(cmd)
get_branches
end
@@ -166,17 +204,17 @@
# '*' 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\/} }
+ @tags = @remote.find_all { |b| b.strip =~ %r{^svn\/tags\/} }
end
def fix_tags
@tags.each do |tag|
tag = tag.strip
- id = tag.gsub(%r{^tags\/}, '').strip
+ id = tag.gsub(%r{^svn\/tags\/}, '').strip
subject = run_command("git log -1 --pretty=format:'%s' #{tag}")
date = run_command("git log -1 --pretty=format:'%ci' #{tag}")
subject = escape_quotes(subject)
date = escape_quotes(date)
id = escape_quotes(id)
@@ -185,30 +223,36 @@
end
end
def fix_branches
svn_branches = @remote.find_all { |b| not @tags.include?(b) }
- svn_branches.each do |branch|
- branch = branch.strip
+ svn_branches = @remote.find_all { |b| b.strip =~ %r{^svn\/} }
+ if @options[:rebase]
+ run_command("git svn fetch")
+ end
+
+ svn_branches.each do |branch|
+ branch = branch.gsub(/^svn\//,'').strip
if @options[:rebase] && (@local.include?(branch) || branch == 'trunk')
- branch = 'master' if branch == 'trunk'
- run_command("git checkout -f #{branch}")
- run_command("git svn rebase")
+ lbranch = branch
+ lbranch = 'master' if branch == 'trunk'
+ run_command("git checkout -f #{lbranch}")
+ run_command("git rebase remotes/svn/#{branch}")
next
end
- next if branch == 'trunk'
- run_command("git branch -t #{branch} remotes/#{branch}")
+ next if branch == 'trunk' || @local.include?(branch)
+ run_command("git branch --track #{branch} remotes/svn/#{branch}")
run_command("git checkout #{branch}")
end
end
def fix_trunk
trunk = @remote.find { |b| b.strip == 'trunk' }
if trunk && ! @options[:rebase]
- run_command("git checkout trunk")
+ run_command("git checkout svn/trunk")
run_command("git branch -D master")
run_command("git checkout -f -b master")
else
run_command("git checkout -f master")
end
@@ -227,11 +271,11 @@
stdout.each do |line|
log line
ret << line
end
end
-
+
ret
end
def log(msg)
puts msg if @options[:verbose]
@@ -240,15 +284,15 @@
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
+ exit -1
end
end
def escape_quotes(str)
str.gsub("'", "'\\\\''")