nirvdrum-svn2git 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,126 @@
1
+ == svn2git
2
+
3
+ +svn2git+ is a tiny utility for migrating projects from Subversion to Git
4
+ while keeping the trunk, branches and tags where they should be. It uses
5
+ git-svn to clone an svn repository and does some clean-up to make sure
6
+ branches and tags are imported in a meaningful way, and that the code checked
7
+ into master ends up being what's currently in your svn trunk rather than
8
+ whichever svn branch your last commit was in.
9
+
10
+ === Examples
11
+
12
+ Say I have this code in svn:
13
+
14
+ trunk
15
+ ...
16
+ branches
17
+ 1.x
18
+ 2.x
19
+ tags
20
+ 1.0.0
21
+ 1.0.1
22
+ 1.0.2
23
+ 1.1.0
24
+ 2.0.0
25
+
26
+ git-svn will go through the commit history to build a new git repo. It will
27
+ import all branches and tags as remote svn branches, whereas what you really
28
+ want is git-native local branches and git tag objects. So after importing this
29
+ project I'll get:
30
+
31
+ $ git branch
32
+ * master
33
+ $ git branch -a
34
+ * master
35
+ 1.x
36
+ 2.x
37
+ tags/1.0.0
38
+ tags/1.0.1
39
+ tags/1.0.2
40
+ tags/1.1.0
41
+ tags/2.0.0
42
+ trunk
43
+ $ git tag -l
44
+ [ empty ]
45
+
46
+ After svn2git is done with your project, you'll get this instead:
47
+
48
+ $ git branch
49
+ * master
50
+ 1.x
51
+ 2.x
52
+ $ git tag -l
53
+ 1.0.0
54
+ 1.0.1
55
+ 1.0.2
56
+ 1.1.0
57
+ 2.0.0
58
+
59
+ Finally, it makes sure the HEAD of master is the same as the current trunk of
60
+ the svn repo.
61
+
62
+ === Installation
63
+
64
+ Make sure you have git installed, then install the gem:
65
+
66
+ $ sudo apt-get install git-core git-svn
67
+ $ sudo gem install svn2git
68
+
69
+ === Usage
70
+
71
+ There are a number of ways in which you can create a git repo from an existing
72
+ svn repo. The differentiating factor is the svn repo layout. Below is an
73
+ enumerated listing of the varying supported layouts and the proper way to
74
+ create a git repo from a svn repo in the specified layout.
75
+
76
+ 1. The svn repo is in the standard layout of (trunk, branches, tags) at the
77
+ root level of the repo.
78
+
79
+ $ svn2git http://svn.yoursite.com/path/to/repo trunk=trunk branches=branches tags=tags
80
+
81
+ 2. The svn repo is NOT in standard layout and has only a trunk and tags at the
82
+ root level of the repo.
83
+
84
+ $ svn2git http://svn.yoursite.com/path/to/repo trunk=trunk tags=tags
85
+
86
+ 3. The svn repo is NOT in standard layout and has only a trunk and branches at
87
+ the root level of the repo.
88
+
89
+ $ svn2git http://svn.yoursite.com/path/to/repo trunk=trunk branches=branches
90
+
91
+ 4. The svn repo is NOT in standard layout and has only a trunk at the root
92
+ level of the repo.
93
+
94
+ $ svn2git http://svn.yoursite.com/path/to/repo trunk=trunk
95
+
96
+ 5. The svn repo is NOT in standard layout and has no trunk, branches, or tags
97
+ at the root level of the repo. Instead the root level of the repo is
98
+ equivalent to the trunk and there are no tags or branches.
99
+
100
+ $ svn2git http://svn.yoursite.com/path/to/repo rootistrunk=true
101
+
102
+ The above will create a git repository in the current directory with the git
103
+ version of the svn repository. Hence, you need to make a directory that you
104
+ want your new git repo to exist in, change into it and then run one of the
105
+ above commands. Note that in the above cases the trunk, branches, tags options
106
+ are simply folder names relative to the provided repo path. For example if you
107
+ specified trunk=foo branches=bar and tags=foobar it would be referencing
108
+ http://svn.yoursite.com/path/to/repo/foo as your trunk, and so on. However, in
109
+ case 5 it references the root of the repo as trunk.
110
+
111
+ === Authors
112
+
113
+ To convert all your svn authors to git format, create a file somewhere on your
114
+ system with the list of conversions to make, one per line, for example:
115
+
116
+ jcoglan = James Coglan <jcoglan@never-you-mind.com>
117
+ stnick = Santa Claus <nicholas@lapland.com>
118
+
119
+ Then pass an +authors+ option to +svn2git+ pointing to your file:
120
+
121
+ svn2git http://repos.com/myproject authors=~/authors.txt
122
+
123
+ Alternatively, you can place the authors file into ~/.svn2git/authors and
124
+ svn2git will load it out of there. This allows you to build up one authors
125
+ file for all your projects and have it loaded for each repository that you
126
+ migrate.
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ require 'rake'
2
+ require 'rake/gempackagetask'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |spec|
7
+ spec.name = "svn2git"
8
+ spec.summary = "A tool for migrating svn projects to git"
9
+ spec.authors = ["James Coglan", "Kevin Menard"]
10
+ spec.homepage = "https://www.negativetwenty.net/redmine/projects/svn2git"
11
+ spec.email = "nirvdrum@gmail.com"
12
+ end
13
+
14
+ rescue LoadError
15
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
16
+ end
17
+
18
+ #
19
+ # spec = Gem::Specification.new do |spec|
20
+ #
21
+ # spec.version = "1.1.0"
22
+ # spec.platform = Gem::Platform::RUBY
23
+ #
24
+ #
25
+ # spec.require_path = "lib"
26
+ # spec.files = FileList["lib/**/*"].to_a
27
+ # spec.autorequire = "lib/svn2git.rb"
28
+ # spec.bindir = "bin"
29
+ # spec.executables = ["svn2git"]
30
+ # spec.default_executable = "svn2git"
31
+ #
32
+ #
33
+ #
34
+ #
35
+ # spec.test_files = FileList["test/**/*"].to_a
36
+ # spec.has_rdoc = true
37
+ # spec.extra_rdoc_files = ["README"]
38
+ # spec.rdoc_options << "--main" << "README" << '--line-numbers' << '--inline-source'
39
+ # end
40
+ #
41
+ # Rake::GemPackageTask.new(spec) do |pkg|
42
+ # pkg.need_tar = true
43
+ # end
44
+ #
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 1
3
+ :major: 1
4
+ :minor: 1
data/bin/svn2git ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright (c) 2008 James Coglan
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'rubygems'
24
+ gem 'svn2git'
25
+
26
+ require 'svn2git'
27
+
28
+ url = ARGV.shift
29
+ options = ARGV.inject({}) do |memo, arg|
30
+ parts = arg.split('=')
31
+ memo[parts.first.to_sym] = parts.last
32
+ memo
33
+ end
34
+
35
+ migration = Svn2Git::Migration.new(url, options)
36
+ migration.run!
37
+
@@ -0,0 +1,120 @@
1
+ module Svn2Git
2
+ DEFAULT_AUTHORS_FILE = "~/.svn2git/authors"
3
+
4
+ class Migration
5
+
6
+ attr_reader :dir
7
+
8
+ def initialize(url, options = {})
9
+ @url = url
10
+ @dir = @url.scan(/[^\/]+/).last
11
+
12
+ @options = options
13
+ @options[:trunk] ||= 'trunk'
14
+ @options[:branches] ||= 'branches'
15
+ @options[:tags] ||= 'tags'
16
+
17
+ @authors = options[:authors]
18
+ if @authors.nil? && File.exists?(File.expand_path(DEFAULT_AUTHORS_FILE))
19
+ @authors = DEFAULT_AUTHORS_FILE
20
+ end
21
+ end
22
+
23
+ def run!
24
+ clone!
25
+ fix_tags
26
+ fix_branches
27
+ fix_trunk
28
+ optimize_repos
29
+ end
30
+
31
+ private
32
+
33
+ def clone!
34
+ trunk = @options[:trunk]
35
+ branches = @options[:branches]
36
+ tags = @options[:tags]
37
+ rootistrunk = @options[:rootistrunk]
38
+
39
+ if (!rootistrunk.nil?)
40
+ # Non-standard repository layout. The repository root is effectively 'trunk.'
41
+ run_command("git svn init --no-metadata --trunk=#{@url}")
42
+
43
+ else
44
+ cmd = "git svn init --no-metadata "
45
+
46
+ # Add each component to the command that was passed as an argument.
47
+ cmd += "--trunk=#{trunk} " unless trunk.nil?
48
+ cmd += "--tags=#{tags} " unless tags.nil?
49
+ cmd += "--branches=#{branches} " unless branches.nil?
50
+
51
+ cmd += @url
52
+
53
+ run_command(cmd)
54
+ end
55
+
56
+ run_command("git config svn.authorsfile #{@authors}") if @authors
57
+ run_command("git svn fetch")
58
+
59
+ get_branches
60
+ end
61
+
62
+ def get_branches
63
+ @remote = `git branch -r`.split(/\n/)
64
+ @tags = @remote.find_all { |b| b.strip =~ %r{^#{@options[:tags]}\/} }
65
+ end
66
+
67
+ def fix_tags
68
+ @tags.each do |tag|
69
+ id = tag.strip.gsub(%r{^#{@options[:tags]}\/}, '')
70
+ subject = `git log -1 --pretty=format:"%s" #{tag.strip()}`
71
+ date = `git log -1 --pretty=format:"%ci" #{tag.strip()}`
72
+ `export GIT_COMMITER_DATE="#{date}"`
73
+ run_command("git tag -a -m '#{subject}' '#{id.strip()}' '#{tag.strip()}'")
74
+ run_command("git branch -d -r #{tag.strip()}")
75
+ end
76
+ end
77
+
78
+ def fix_branches
79
+ svn_branches = @remote.find_all { |b| not @tags.include?(b) }
80
+ svn_branches.each do |branch|
81
+ branch = branch.strip
82
+ next if branch == 'trunk'
83
+ run_command("git checkout #{branch}")
84
+ run_command("git checkout -b #{branch}")
85
+ end
86
+ end
87
+
88
+ def fix_trunk
89
+ trunk = @remote.find { |b| b.strip == 'trunk' }
90
+ if trunk
91
+ run_command("git checkout trunk")
92
+ run_command("git branch -D master")
93
+ run_command("git checkout -f -b master")
94
+ run_command("git branch -d -r trunk")
95
+ end
96
+ end
97
+
98
+ def optimize_repos
99
+ run_command("git gc")
100
+ end
101
+
102
+ def run_command(cmd)
103
+ log "Running command: #{cmd}"
104
+
105
+ IO.popen(cmd) do |stdout|
106
+ stdout.each do |line|
107
+ log line
108
+ end
109
+ end
110
+ end
111
+
112
+ private
113
+
114
+ def log(msg)
115
+ puts msg if @options[:verbose]
116
+ end
117
+
118
+ end
119
+ end
120
+
data/lib/svn2git.rb ADDED
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/svn2git/migration'
2
+
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nirvdrum-svn2git
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.1
5
+ platform: ruby
6
+ authors:
7
+ - James Coglan
8
+ - Kevin Menard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-04-15 00:00:00 -07:00
14
+ default_executable: svn2git
15
+ dependencies: []
16
+
17
+ description:
18
+ email: nirvdrum@gmail.com
19
+ executables:
20
+ - svn2git
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - README
25
+ files:
26
+ - Rakefile
27
+ - VERSION.yml
28
+ - bin/svn2git
29
+ - lib/svn2git.rb
30
+ - lib/svn2git/migration.rb
31
+ - README
32
+ has_rdoc: true
33
+ homepage: https://www.negativetwenty.net/redmine/projects/svn2git
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --charset=UTF-8
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.2.0
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: A tool for migrating svn projects to git
58
+ test_files: []
59
+