Skip to content
Newer
Older
100755 516 lines (434 sloc) 17 KB
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
1 #!/usr/bin/env ruby
648f1b6 Add author header and a note about running in a empty directory
Steve authored Oct 11, 2007
2 ##
3 ## Author: Steve Purcell, http://www.sanityinc.com/
4 ## Obtain the latest version of this software here: http://git.sanityinc.com/
5 ##
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
6
ea74920 @nominolo Update TODOs
nominolo authored May 9, 2008
7 # XXX: make backwards compatible
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
8 # TODO: import parallel darcs repos as git branches, identifying branch points
ea74920 @nominolo Update TODOs
nominolo authored May 8, 2008
9 # TODO: use default repo if none was supplied
ae775b5 @purcell Return to storing darcs-hash in commit comments, but provide an optio…
authored May 12, 2008
10 # TODO: handle *-darcs-backupN files?
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
11
12 require 'ostruct'
13 require 'rexml/document'
24157c1 @nominolo Add argument handling and add argument for default email address
nominolo authored May 7, 2008
14 require 'optparse'
76cbfc2 @nominolo Allow listing of authors
nominolo authored May 9, 2008
15 require 'yaml'
518b74a @jmah Add borings to the global darcs boring file
jmah authored Aug 29, 2009
16 require 'pathname'
e6ddd9e @kerneis Strip invalid byte sequences from input
kerneis authored Mar 9, 2010
17 require 'iconv'
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
18
c547c01 @nominolo Proper handling of timezones
nominolo authored May 7, 2008
19 # Explicitly setting a time zone would cause darcs to only output in
20 # that timezone hence we couldn't get the actual patch TZ
21 # ENV['TZ'] = 'GMT0'
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
22
c213d24 @nominolo Move darcs hashes out of commit messages. By default they now go into
nominolo authored May 7, 2008
23 GIT_PATCHES = ".git/darcs_patches"
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 11, 2008
24 DEFAULT_AUTHOR_MAP_FILE = ".git/darcs_author_substitutions"
25
26 # -------------------------------------------------------------------------------
27 # Usage info and argument parsing
28 # -------------------------------------------------------------------------------
b0d3292 @purcell Add more details usage info, as requested by Samuel Bronson
authored Feb 17, 2008
29
51249de @thomie Add non-nil default values for name and email.
thomie authored Aug 15, 2010
30 OPTIONS = { :default_author => 'none',
31 :default_email => 'none',
6e40cd3 @nominolo Add some more options
nominolo authored May 9, 2008
32 :list_authors => false,
33 :author_map => nil,
ae775b5 @purcell Return to storing darcs-hash in commit comments, but provide an optio…
authored May 12, 2008
34 :clean_commit_messages => false,
f5bf94d @purcell Clean up logic linking --patches option and running of post-flight co…
authored May 12, 2008
35 :num_patches => nil }
24157c1 @nominolo Add argument handling and add argument for default email address
nominolo authored May 7, 2008
36 opts = OptionParser.new do |opts|
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
37 opts.banner = <<-end_usage
38 Creates git repositories from darcs repositories
24157c1 @nominolo Add argument handling and add argument for default email address
nominolo authored May 7, 2008
39
40 usage: darcs-to-git DARCSREPODIR [options]
b0d3292 @purcell Add more details usage info, as requested by Samuel Bronson
authored Feb 17, 2008
41
42
43 1. Create an *empty* directory that will become the new git repository
44 2. From inside that directory, run this program, passing the location
ada5bc8 @asjo Hint at the fact that the darcs repository must be a local one.
asjo authored Mar 19, 2008
45 of the local source darcs repo as a parameter
b0d3292 @purcell Add more details usage info, as requested by Samuel Bronson
authored Feb 17, 2008
46
47 The program will git-init the empty directory, and migrate all patches
48 in the source darcs repo into commits in that repository.
49
50 Thereafter, incremental patch conversion from the same source repo is
51 possible by repeating step 2.
24157c1 @nominolo Add argument handling and add argument for default email address
nominolo authored May 7, 2008
52
53218c8 @nominolo Document that only the first tag will be applied.
nominolo authored May 7, 2008
53 NOTE: In case of multiple tags, only the first one will be applied.
54 If you really need to, you can manually identify the patch and use
55 \"git tag -f <tagname> <sha1-of-commit-before-tagging>\".
56
57 OPTIONS
58
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
59 end_usage
e6dbc64 @thomie Add default_author option.
thomie authored Aug 13, 2010
60 opts.on('--default-author NAME',
61 "Set the author name used when darcs patch has no explicit author") do |m|
62 OPTIONS[:default_author] = m
63 end
1311774 @nominolo Remove short options
nominolo authored May 9, 2008
64 opts.on('--default-email ADDRESS',
24157c1 @nominolo Add argument handling and add argument for default email address
nominolo authored May 7, 2008
65 "Set the email address used when no explicit address is given") do |m|
6e40cd3 @nominolo Add some more options
nominolo authored May 8, 2008
66 OPTIONS[:default_email] = m
67 end
1311774 @nominolo Remove short options
nominolo authored May 9, 2008
68 opts.on('--list-authors',
6e40cd3 @nominolo Add some more options
nominolo authored May 8, 2008
69 "List all unique authors in source repo and quit.") do |m|
70 OPTIONS[:list_authors] = m
71 end
1311774 @nominolo Remove short options
nominolo authored May 9, 2008
72 opts.on('--author-map FILE',
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
73 "Supply a YAML file that maps committer names to canonical author names") do |f|
6e40cd3 @nominolo Add some more options
nominolo authored May 8, 2008
74 OPTIONS[:author_map] = f
75 end
76 opts.on('--patches [N]', OptionParser::DecimalInteger,
77 "Only pull N patches.") do |n|
f5bf94d @purcell Clean up logic linking --patches option and running of post-flight co…
authored May 12, 2008
78 abort opts.to_s unless n >= 0
6e40cd3 @nominolo Add some more options
nominolo authored May 8, 2008
79 OPTIONS[:num_patches] = n
24157c1 @nominolo Add argument handling and add argument for default email address
nominolo authored May 7, 2008
80 end
ae775b5 @purcell Return to storing darcs-hash in commit comments, but provide an optio…
authored May 12, 2008
81 opts.on('--clean-commit-messages',
82 "Don't note darcs hashes in git commit messages (not recommended)") do |n|
83 OPTIONS[:clean_commit_messages] = true
84 end
4271fa3 add --version option => make help2man happy
Simon Huerlimann authored Jan 2, 2009
85 opts.on('--version', "Output version information and exit") do
86 puts <<-EOF
87 darcs-to-git 0.1
88
89 Copyright (c) 2009 Steve Purcell, http://www.sanityinc.com/
90
91 License MIT: <http://www.opensource.org/licenses/mit-license.php>
92 This is free software: you are free to change and redistribute it.
93 There is NO WARRANTY, to the extent permitted by law.
94 EOF
95 exit
96 end
97
2690e4b @purcell Add a --help option
authored May 12, 2008
98 opts.on('-h', '--help', "Show this message") do
3b11516 exit with 0, not 1 if explicitly called with --help or -h
Simon Huerlimann authored Jan 2, 2009
99 puts opts.to_s
100 exit
2690e4b @purcell Add a --help option
authored May 12, 2008
101 end
24157c1 @nominolo Add argument handling and add argument for default email address
nominolo authored May 7, 2008
102 end
103 opts.parse!
104
105 SRCREPO = ARGV[0]
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
106 if SRCREPO.nil?
2690e4b @purcell Add a --help option
authored May 12, 2008
107 abort opts.to_s
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
108 elsif !FileTest.exists?(SRCREPO + '/_darcs')
109 abort "#{SRCREPO} is not a valid local darcs repository"
de433de @purcell Add -h/--help switches (requested by Brenda Wallace)
authored Feb 17, 2008
110 end
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
111
bd442b4 @purcell Move DarcsPatch#decode_darcs_escape to String#darcs_unescape
authored May 10, 2008
112
113 # -------------------------------------------------------------------------------
114 # Utilities
115 # -------------------------------------------------------------------------------
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
116 def run(*args)
117 puts "Running: #{args.inspect}"
118 system(*args) || raise("Failed to run: #{args.inspect}")
119 end
120
e6ddd9e @kerneis Strip invalid byte sequences from input
kerneis authored Mar 9, 2010
121 # cf. Paul Battley, http://po-ru.com/diary/fixing-invalid-utf-8-in-ruby-revisited/
122 def validate_utf8(s)
123 return Iconv.iconv('UTF-8//IGNORE', 'UTF-8', (s + ' ') ).first[0..-2]
124 end
125
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
126 def output_of(*args)
127 puts "Running: #{args.inspect}"
128 output = IO.popen(args.map {|a| "'#{a}'"}.join(' '), 'r') { |p| p.read }
129 if $?.exitstatus == 0
e6ddd9e @kerneis Strip invalid byte sequences from input
kerneis authored Mar 9, 2010
130 return validate_utf8(output)
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
131 else
132 raise "Failed to run: #{args.inspect}"
133 end
134 end
135
a110c04 @purcell Provide and use Symbol#to_proc
authored May 11, 2008
136 class Symbol
137 def to_proc() lambda { |o| o.send(self) } end
138 end
139
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
140 class String
bd442b4 @purcell Move DarcsPatch#decode_darcs_escape to String#darcs_unescape
authored May 10, 2008
141 def darcs_unescape
142 # darcs uses '[_\hh_]' to quote non-ascii characters where 'h' is
143 # a hexadecimal. We translate this to '=hh' and use ruby's unpack
144 # to do replace this with the proper byte.
145 gsub(/\[\_\\(..)\_\]/) { |x| "=#{$1}" }.unpack("M*")[0]
146 end
147 end
148
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
149
150 # -------------------------------------------------------------------------------
151 # Map darcs authors to git authors
152 # -------------------------------------------------------------------------------
153 class AuthorMap < Hash
154 attr_accessor :default_email
e6dbc64 @thomie Add default_author option.
thomie authored Aug 13, 2010
155 attr_accessor :default_author
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
156
157 def self.load(filename)
158 new.merge(YAML.load_file(filename))
159 end
160
161 # gives the name and email
162 def [](author)
163 name_and_email(super || author)
164 end
165
166 private
167
168 def name_and_email(author)
40bb362 @purcell Tidy up author/email regex code
authored May 12, 2008
169 case author
170 when /^\s*(\S.*?)\s*\<(\S+@\S+?)\>\s*$/
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
171 [$1, $2]
40bb362 @purcell Tidy up author/email regex code
authored May 12, 2008
172 when /^\s*\<?(\S+@\S+?)\>?\s*$/
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
173 email = $1
174 [email.split('@').first, email]
e6dbc64 @thomie Add default_author option.
thomie authored Aug 13, 2010
175 when ''
176 [default_author, default_email]
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
177 else
178 [author, default_email]
179 end
180 end
181 end
182
c8bfc11 @purcell Replace $darcs_patches_in_git with CommitHistory class
authored May 11, 2008
183 # -------------------------------------------------------------------------------
184 # Storing a history of related darcs and git commits
185 # -------------------------------------------------------------------------------
186
187 class CommitHistory
188 def initialize(patch_file_name)
189 @patch_file_name = patch_file_name
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
190 @darcs_patches_in_git = {}
191 if File.exists?(patch_file_name)
192 @darcs_patches_in_git = YAML.load_file(patch_file_name)
193 unless @darcs_patches_in_git.is_a?(Hash)
194 raise "yaml hash not found in #{patch_file_name}"
195 end
196 else
ae775b5 @purcell Return to storing darcs-hash in commit comments, but provide an optio…
authored May 12, 2008
197 # TODO: consider doing this unconditionally, since that
198 # might allow merging between repositories created with darcs-to-git
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
199 fill_from_darcs_hash_comments
200 end
c8bfc11 @purcell Replace $darcs_patches_in_git with CommitHistory class
authored May 11, 2008
201 end
202
203 def record_git_commit(commit_id, identifier)
204 # using one file per darcs patch would be an incredible waste of space
205 # on my system one file takes up 4K even if only a few bytes are in it
206 # hence we just use a simple YAML hash
207 @darcs_patches_in_git[identifier] = commit_id
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
208 File.open(@patch_file_name, 'w') do |f|
209 YAML.dump(@darcs_patches_in_git, f)
c8bfc11 @purcell Replace $darcs_patches_in_git with CommitHistory class
authored May 11, 2008
210 end
211 end
212
213 def find_git_commit(is_tag, git_tag_name, identifier)
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
214 if is_tag
6c83a4e Prevent error when copying first darcs 2 tag to git 1.6 repo
Suraj N. Kurapati authored Sep 21, 2008
215 (output_of("git", "tag", "-l") rescue "").split(/\r?\n/).include?(git_tag_name) &&
38d026d @purcell Use "git subcommand" rather than "git-subcommand", for git 1.6 compat…
authored Aug 25, 2008
216 output_of("git", "rev-list", "--max-count=1", "tags/#{git_tag_name}").strip
c8bfc11 @purcell Replace $darcs_patches_in_git with CommitHistory class
authored May 11, 2008
217 else
218 @darcs_patches_in_git[identifier];
219 end
220 end
c6a1881 @purcell Use a more reliable trick to determine if the git repo is empty
authored May 12, 2008
221
222 def empty_repo?
223 !system("git rev-parse --verify HEAD >/dev/null 2>&1")
224 end
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
225
15c7ac6 @thomie Check only once if git repo is empty. Faster.
thomie authored Aug 15, 2010
226 private
227
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
228 def fill_from_darcs_hash_comments
229 return if empty_repo?
6e650f2 @thomie Add "--no-color" argument to git log command.
thomie authored Aug 15, 2010
230 Array(output_of("git", "log", "--grep=darcs-hash:", "--nocolor").split(/^commit /m)[1..-1]).each do |entry|
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
231 commit_id, identifier = entry.scan(/^([a-z0-9]+$).*darcs-hash:(.*?)$/sm).flatten
232 record_git_commit(commit_id, identifier)
233 end
234 end
c8bfc11 @purcell Replace $darcs_patches_in_git with CommitHistory class
authored May 11, 2008
235 end
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
236
237 # -------------------------------------------------------------------------------
238 # Reading darcs patches and applying them to a git repo
239 # -------------------------------------------------------------------------------
240
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
241 class DarcsPatch
9685ea2 @purcell Include patch comment as well as just name (thanks Antti-Juhani Kaija…
authored Oct 28, 2007
242 attr_accessor :source_repo, :author, :date, :inverted, :identifier, :name, :is_tag, :git_tag_name, :comment
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
243 attr_reader :git_author_name, :git_author_email
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
244
245 def initialize(source_repo, patch_xml)
246 self.source_repo = source_repo
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
247 self.author = patch_xml.attribute('author').value.darcs_unescape
c547c01 @nominolo Proper handling of timezones
nominolo authored May 7, 2008
248 self.date = darcs_date_to_git_date(patch_xml.attribute('date').value,
249 patch_xml.attribute('local_date').value)
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
250 self.inverted = (patch_xml.attribute('inverted').to_s == 'True')
251 self.identifier = patch_xml.attribute('hash').to_s
bd442b4 @purcell Move DarcsPatch#decode_darcs_escape to String#darcs_unescape
authored May 10, 2008
252 self.name = patch_xml.get_elements('name').first.get_text.value.darcs_unescape rescue 'Unnamed patch'
253 self.comment = patch_xml.get_elements('comment').first.get_text.value.darcs_unescape rescue nil
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
254 if (self.is_tag = (self.name =~ /^TAG (.*)/))
a11efbc @kerneis Escape stars in tag names
kerneis authored Mar 16, 2010
255 self.git_tag_name = $1.gsub(/[\s:.*]+/, '_')
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
256 end
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
257 @git_author_name, @git_author_email = AUTHOR_MAP[author]
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
258 end
259
260 def <=>(other)
261 self.identifier <=> other.identifier
262 end
263
264 def git_commit_message
4f0a3fd @caldwell Make --clean-commit-messages also remove darcs' ugly "Ignore-This" he…
caldwell authored Mar 18, 2010
265 patch_name = ((inverted ? "UNDO: #{name}" : name) unless name =~ /^\[\w+ @ \d+\]/)
266 OPTIONS[:clean_commit_messages] ? [ patch_name, comment && comment.gsub(/^Ignore-this:.*$/, '')].compact.join("\n") \
267 : [ patch_name, comment, "darcs-hash:#{identifier}" ].compact.join("\n\n")
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
268 end
269
270 def self.read_from_repo(repo)
7220bb8 @nominolo Cosmetics
nominolo authored May 9, 2008
271 REXML::Document.new(output_of("darcs", "changes", "--reverse",
272 "--repodir=#{repo}", "--xml",
6133a71 @thomie Use darcs changes --no-summary.
thomie authored Aug 15, 2010
273 "--no-summary")).
7220bb8 @nominolo Cosmetics
nominolo authored May 9, 2008
274 get_elements('changelog/patch').map do |p|
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
275 DarcsPatch.new(repo, p)
276 end
277 end
278
279 # Return committish for corresponding patch in current git repo, or false/nil
280 def id_in_git_repo
32c084f @thomie Check only once if commit already in git repo.
thomie authored Aug 15, 2010
281 COMMIT_HISTORY.find_git_commit(is_tag, git_tag_name, identifier)
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
282 end
283
284 def pull_and_apply
285 puts "\n" + ("=" * 80)
f76d7f2 Better handling for darcs changeset authors in rfc822 format ("blah <…
Steve authored Oct 17, 2007
286 puts "PATCH : #{name}"
287 puts "DATE : #{date}"
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
288 puts "AUTHOR: #{author} => #{git_author_name} <#{git_author_email}>"
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
289 puts "=" * 80
290
291 pull
38d026d @purcell Use "git subcommand" rather than "git-subcommand", for git 1.6 compat…
authored Aug 25, 2008
292 system("git", "status")
6d8c857 @purcell Check that darcs reports the working area as clean before pulling the…
authored May 12, 2008
293 commit_to_git_repo
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
294 end
295
296 private
297
298 def pull
6d8c857 @purcell Check that darcs reports the working area as clean before pulling the…
authored May 12, 2008
299 unless darcs_reports_clean_repo?
300 raise "Darcs reports dirty repo before pulling #{identifier}; confused, so aborting"
301 end
7220bb8 @nominolo Cosmetics
nominolo authored May 9, 2008
302 run("darcs", "pull", "--all", "--quiet",
303 "--match", "hash #{identifier}",
304 "--set-scripts-executable", source_repo)
6d8c857 @purcell Check that darcs reports the working area as clean before pulling the…
authored May 12, 2008
305 unless darcs_reports_clean_repo?
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
306 puts "Darcs reports dirty directory: assuming conflict that is fixed by a later patch... reverting"
307 run("darcs revert --all")
5e8f292 @jmah Handle conflict backup files with spaces
jmah authored Aug 29, 2009
308 run("find . -name '*-darcs-backup0' -exec rm -f {} \\;") # darcs2 creates these
8cdff36 @thomie Do third check for clean directory only if needed.
thomie authored Aug 15, 2010
309 unless darcs_reports_clean_repo?
39f0e06 @smcv Fix repository cleanup after pull
smcv authored Jul 10, 2008
310 system("darcs whatsnew -sl")
311 raise "Failed to clean repo, see above"
8cdff36 @thomie Do third check for clean directory only if needed.
thomie authored Aug 15, 2010
312 end
39f0e06 @smcv Fix repository cleanup after pull
smcv authored Jul 10, 2008
313 end
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
314 end
315
6d8c857 @purcell Check that darcs reports the working area as clean before pulling the…
authored May 12, 2008
316 def darcs_reports_clean_repo?
2c82461 @adrianheine Ignore the 'darcs_testing_for_nfs' dir created by darcs in repos on N…
adrianheine authored May 11, 2010
317 `darcs whatsnew -sl | egrep -v '^a (\./)?\.git(/|$)' | egrep -v '^a ./darcs_testing_for_nfs/$'` =~ /^(No changes!)?$/
6d8c857 @purcell Check that darcs reports the working area as clean before pulling the…
authored May 12, 2008
318 end
319
320 def commit_to_git_repo
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
321 ENV['GIT_AUTHOR_NAME'] = ENV['GIT_COMMITTER_NAME'] = git_author_name
322 ENV['GIT_AUTHOR_EMAIL'] = ENV['GIT_COMMITTER_EMAIL'] = git_author_email
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
323 ENV['GIT_AUTHOR_DATE'] = ENV['GIT_COMMITTER_DATE'] = date
324 if is_tag
38d026d @purcell Use "git subcommand" rather than "git-subcommand", for git 1.6 compat…
authored Aug 25, 2008
325 run("git", "tag", "-a", "-m", git_commit_message, git_tag_name)
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
326 else
327 if (new_files = git_new_files).any?
53f23cc @jmah Add files even if they would be ignored by git
jmah authored Aug 29, 2009
328 run(*(["git", "add", "-f"] + new_files))
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
329 end
4f630f3 @purcell Improved parsing of git-ls-files output, which changed with a git rel…
authored Oct 27, 2007
330 if git_changed_files.any? || new_files.any?
38d026d @purcell Use "git subcommand" rather than "git-subcommand", for git 1.6 compat…
authored Aug 25, 2008
331 run("git", "commit", "-a", "-m", git_commit_message)
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
332 end
0571c80 @nominolo Unconditionally record commit id for darcs patch.
nominolo authored May 9, 2008
333 # get full id of last commit and associate it with the patch id
6e650f2 @thomie Add "--no-color" argument to git log command.
thomie authored Aug 15, 2010
334 commit_id = output_of("git", "log", "-n1", "--no-color").scan(/^commit ([a-z0-9]+$)/).flatten.first
c8bfc11 @purcell Replace $darcs_patches_in_git with CommitHistory class
authored May 11, 2008
335 COMMIT_HISTORY.record_git_commit(commit_id, identifier)
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
336 end
337 end
338
c547c01 @nominolo Proper handling of timezones
nominolo authored May 7, 2008
339 def darcs_date_to_git_date(utc,local)
7a488be @nominolo Improve documentation for timezone extraction
nominolo authored May 9, 2008
340 # Calculates a git-friendly date (e.g., timezone CET decribed as
341 # +0100) by using the two date fields that darcs gives us: a list
342 # of numbers describing the UTC time and a local time formatted in
343 # a human-readable format. We could parse the local time and
344 # derive the timezone offset from the timezone name. but timezones
345 # aren't well-defined, so we ignore the timezone name and instead
346 # calculate the timezone offset ourselves by calculating the
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
347 # difference between local time and UTC time.
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
348 if not utc =~ /^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/
c547c01 @nominolo Proper handling of timezones
nominolo authored May 7, 2008
349 raise "Wrong darcs date format"
350 end
351 utc_time = Time.utc($1,$2,$3,$4,$5,$6)
7a488be @nominolo Improve documentation for timezone extraction
nominolo authored May 9, 2008
352 # example: Mon Oct 2 14:23:28 CEST 2006
353 # everything except timezone name is fixed-length, if parsing
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
354 # fails we just use UTC
7a488be @nominolo Improve documentation for timezone extraction
nominolo authored May 9, 2008
355 pat = /^\w\w\w (\w\w\w) ([ 1-9]\d) ([ 0-9]\d)\:(\d\d)\:(\d\d) \w* (\d\d\d\d)/
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
356 local_time = if pat =~ local
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
357 Time.utc($6,$1,$2,$3,$4,$5)
358 else
359 utc_time
360 end
7a488be @nominolo Improve documentation for timezone extraction
nominolo authored May 9, 2008
361 offs = local_time - utc_time # time offset in seconds
c547c01 @nominolo Proper handling of timezones
nominolo authored May 7, 2008
362 t = local_time
7a488be @nominolo Improve documentation for timezone extraction
nominolo authored May 9, 2008
363 # formats the above example as: 2006-10-02 14:23:28 +0200
364 s = sprintf("%4d-%02d-%02d %02d:%02d:%02d %s%02d%02d",
365 t.year, t.month, t.day,
c547c01 @nominolo Proper handling of timezones
nominolo authored May 7, 2008
366 t.hour, t.min, t.sec,
7a488be @nominolo Improve documentation for timezone extraction
nominolo authored May 9, 2008
367 offs < 0 ? "-" : "+", offs.abs/3600, offs.abs.modulo(3600)/60 )
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
368 end
369
4f630f3 @purcell Improved parsing of git-ls-files output, which changed with a git rel…
authored Oct 27, 2007
370 def git_ls_files(wanted)
38d026d @purcell Use "git subcommand" rather than "git-subcommand", for git 1.6 compat…
authored Aug 25, 2008
371 output_of(*["git", "ls-files", "-t", "-o", "-m", "-d", "-z", "-X", ".git/info/exclude"]).scan(/(.?) (.*?)\0/m).map do |code, name|
4f630f3 @purcell Improved parsing of git-ls-files output, which changed with a git rel…
authored Oct 27, 2007
372 name if wanted.include?(code)
373 end.compact
374 end
375 def git_new_files() git_ls_files(["?"]) end
376 def git_changed_files() git_ls_files(%w(? R C)) end
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
377 end
378
76cbfc2 @nominolo Allow listing of authors
nominolo authored May 9, 2008
379 def extract_authors(patches)
380 unique_authors = {}
381 patches.each do |p|
382 unique_authors[p.author] =
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
383 "#{p.git_author_name}" + (p.git_author_email.nil? ? "" : " <#{p.git_author_email}>")
76cbfc2 @nominolo Allow listing of authors
nominolo authored May 9, 2008
384 end
385 puts "# You can use the following output as a starting point for an author_map"
386 puts "# Just fill in the proper text after the colon; put email addresses in"
387 puts "# angle brackets. You can remove any lines that look OK to you."
388 # TODO: Can we make the output sorted?
389 puts YAML::dump( unique_authors )
390 end
391
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
392
393 # -------------------------------------------------------------------------------
394 # Pre-flight checks
395 # -------------------------------------------------------------------------------
396
11ffabe @purcell Properly initialise conversion repo when converting old-format darcs …
authored Nov 22, 2008
397 DARCS_VERSION = output_of(*%w(darcs -v)).scan(/(\d+)\.(\d+)\.(\d+)/).flatten.map {|v| v.to_i}
b88ae01 Add support for darcs2 repositories.
Suraj N. Kurapati authored Sep 21, 2008
398
399 def darcs2_repo?(repo)
400 begin
11ffabe @purcell Properly initialise conversion repo when converting old-format darcs …
authored Nov 22, 2008
401 output_of("darcs", "show", "repo", "--repodir=#{repo}") =~ /Format:.*darcs-2/
b88ae01 Add support for darcs2 repositories.
Suraj N. Kurapati authored Sep 22, 2008
402 rescue # darcs1 does not have a "show" command, so we get an exception
11ffabe @purcell Properly initialise conversion repo when converting old-format darcs …
authored Nov 22, 2008
403 false
b88ae01 Add support for darcs2 repositories.
Suraj N. Kurapati authored Sep 22, 2008
404 end
405 end
406
4cce98f @purcell Add darcs version check and warning, due to known issues with darcs 1…
authored Feb 22, 2008
407 class Array; include Comparable; end
408
11ffabe @purcell Properly initialise conversion repo when converting old-format darcs …
authored Nov 22, 2008
409 unless DARCS_VERSION > [1, 0, 7]
4cce98f @purcell Add darcs version check and warning, due to known issues with darcs 1…
authored Feb 22, 2008
410 STDERR.write("WARNING: your darcs appears to be old, and may not work with this script\n")
411 end
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
412
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
413
414 # -------------------------------------------------------------------------------
415 # Initialise the working area
416 # -------------------------------------------------------------------------------
bf4f1ba @purcell Set PAGER / GIT_PAGER to 'cat' globally (thanks Samium Gromoff)
authored Nov 22, 2008
417 ENV['GIT_PAGER'] = ENV['PAGER'] = "cat" # so that pager of git-log doesn't halt conversion
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
418
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
419 unless File.directory?("_darcs")
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
420 puts "Initialising the working area."
b88ae01 Add support for darcs2 repositories.
Suraj N. Kurapati authored Sep 22, 2008
421
422 darcs_init = %w(darcs init)
11ffabe @purcell Properly initialise conversion repo when converting old-format darcs …
authored Nov 22, 2008
423 if darcs2_repo?(SRCREPO)
424 darcs_init << "--darcs-2"
425 elsif DARCS_VERSION >= [2, 0, 0]
426 darcs_init << "--old-fashioned-inventory"
427 end
b88ae01 Add support for darcs2 repositories.
Suraj N. Kurapati authored Sep 22, 2008
428 run(*darcs_init)
429
38d026d @purcell Use "git subcommand" rather than "git-subcommand", for git 1.6 compat…
authored Aug 25, 2008
430 run("git", "init")
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
431 File.open(".git/info/exclude", "a") { |f| f.write("_darcs\n.DS_Store\n") }
518b74a @jmah Add borings to the global darcs boring file
jmah authored Aug 29, 2009
432
433 # Patterns to exclude
434 git_borings = [] << '(^|/)\.git($|/)' << '(^|/)\.DS_Store$'
435 existing_borings = []
436
437 # Check existing global boring patterns
438 global_darcs_dir = Pathname.new("#{ENV['HOME']}/.darcs")
439 global_boring_file = global_darcs_dir + 'boring'
440 if global_boring_file.exist?
441 existing_borings = File.open(global_boring_file, 'r') {|f| f.readlines}.map {|l| l.chomp }
442 else
443 global_darcs_dir.mkdir unless global_darcs_dir.directory?
444 end
445
446 # Add boring patterns to global boring file
447 File.open(global_boring_file, 'a') do |f|
448 (git_borings - existing_borings).each {|b| f.puts b }
449 end
450
7f35b89 @nominolo Add TODO
nominolo authored May 9, 2008
451 # TODO: migrate darcs borings into git excludes?
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
452 end
453
3de3836 @purcell Smoothly convert existing "darcs-hash:" metadata into the new-style Y…
authored May 12, 2008
454
455 COMMIT_HISTORY = CommitHistory.new(GIT_PATCHES)
456
87433cc Initial version, working for single-branch imports with tags
Steve authored Sep 12, 2007
457
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
458 AUTHOR_MAP = if OPTIONS[:author_map]
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
459 AuthorMap.load(OPTIONS[:author_map])
460 elsif File.exists?(DEFAULT_AUTHOR_MAP_FILE)
461 AuthorMap.load(DEFAULT_AUTHOR_MAP_FILE)
462 else
463 AuthorMap.new
464 end
e6dbc64 @thomie Add default_author option.
thomie authored Aug 13, 2010
465 AUTHOR_MAP.default_author = OPTIONS[:default_author]
0bfb333 @purcell Some tidyup work, particularly regarding author maps
authored May 10, 2008
466 AUTHOR_MAP.default_email = OPTIONS[:default_email]
ca12ee3 @nominolo Remember author substitition map
nominolo authored May 9, 2008
467
c8bfc11 @purcell Replace $darcs_patches_in_git with CommitHistory class
authored May 11, 2008
468
38670d8 Support incremental pulling when some old patches were no-ops (e.g. e…
Steve authored Sep 17, 2007
469 patches = DarcsPatch.read_from_repo(SRCREPO)
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
470 if OPTIONS[:list_authors]
76cbfc2 @nominolo Allow listing of authors
nominolo authored May 9, 2008
471 extract_authors(patches)
472 exit(0)
473 end
38670d8 Support incremental pulling when some old patches were no-ops (e.g. e…
Steve authored Sep 17, 2007
474
15c7ac6 @thomie Check only once if git repo is empty. Faster.
thomie authored Aug 15, 2010
475 if COMMIT_HISTORY.empty_repo?
476 patches_available = patches
477 else
478 patches_available = patches.find_all { |p| not p.id_in_git_repo }
38670d8 Support incremental pulling when some old patches were no-ops (e.g. e…
Steve authored Sep 17, 2007
479 end
480
f5bf94d @purcell Clean up logic linking --patches option and running of post-flight co…
authored May 12, 2008
481 patches_to_pull = if OPTIONS[:num_patches]
482 patches_available.first(OPTIONS[:num_patches])
483 else
484 patches_available
485 end
abbefc5 @nominolo Allow limiting the number of patches to pull
nominolo authored May 9, 2008
486
a110c04 @purcell Provide and use Symbol#to_proc
authored May 11, 2008
487 patches_to_pull.each &:pull_and_apply
a1fe601 @nominolo Hint at the usefulness of 'git gc'
nominolo authored May 7, 2008
488
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
489 pulled = patches_to_pull.size
490 if pulled == 0
491 puts "\nNothing to pull."
492 else
493 puts "\nPulled #{pulled} patch#{"es" unless pulled == 1}."
494 puts "\nDarcs import successful! You may now want to run `git gc' to
a1fe601 @nominolo Hint at the usefulness of 'git gc'
nominolo authored May 7, 2008
495 improve space usage the git repo"
a6b9f7e @nominolo Add consistency check after import.
nominolo authored May 7, 2008
496 end
497
f5bf94d @purcell Clean up logic linking --patches option and running of post-flight co…
authored May 12, 2008
498
499 # -------------------------------------------------------------------------------
500 # Post-flight checks
501 # -------------------------------------------------------------------------------
502
503 # if we didn't pull all patches, then the consistency check would
504 # fail, so we simply skip it
505 if patches_to_pull.size == patches_available.size
ffd9c8d @purcell Tidy up consistency check code, and fix some unidiomatic constructions
authored May 12, 2008
506 puts "Comparing final state with source repo..."
507 system("diff", "-ur", "-x", "_darcs", "-x", ".git", ".", SRCREPO)
508 if $? != 0
509 abort <<-end_msg
510 !!! There were differences! See diff above for details.
511 !!! It may be that the source repository was dirty.
512 !!! Run "cd #{SRCREPO} && darcs whatsnew -sl" to check.
513 end_msg
514 end
515 end
Something went wrong with that request. Please try again.