git-si 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7bf20760b268eea61a8be1559cbb9021308312f1
4
- data.tar.gz: 5b3e9643cdd6c24bb1fb4c400b06bc4845068b16
3
+ metadata.gz: f699eab35b01983b28c6a305f4f052bff51c877b
4
+ data.tar.gz: 66757783cb35d72353a1aea64c982148114771d5
5
5
  SHA512:
6
- metadata.gz: 9d65955697dd0fc1e1b4b25421143cff2a690ba6d29b65ce39d699621a09d9963e8a4d231f77f2cbbb5768c06611634717cba9acb7d01f45c21532944f2b7ddc
7
- data.tar.gz: d65170ca5833a3da1507c587d8e14d8a9f54a511dc54480bd7c8fa474d01718ee57ede7830db06103bdace19a61953fdfb7a36a9e8639971e3a5760e579066b4
6
+ metadata.gz: 7f47abf1fc81a97582940b27708e1e362c30d0947fb3d19017c7a91a07243704742d837d47eaf67b6273ad06209ebd570edeaa5781818b3f4f936494f75c54af
7
+ data.tar.gz: df346172fd8e64b4ef85cbcf106fa9d8952b8005fdf91ecfdf228d29b87bc60c76e6310b1d462372df3bb743c43fa35ea134c39b038cbd6bf542fbcd61d7cd2d
data/git-si.gemspec CHANGED
@@ -18,10 +18,11 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "bundler"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "thor"
24
24
  spec.add_development_dependency "pager"
25
+ spec.add_development_dependency "rspec"
25
26
 
26
27
  spec.add_runtime_dependency "thor"
27
28
  spec.add_runtime_dependency "pager"
data/lib/git/si.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  require "git/si/version"
2
+ require "git/si/errors"
3
+ require "git/si/svn-control"
4
+ require "git/si/git-control"
5
+ require "git/si/git-ignore"
6
+ require "git/si/util"
7
+ require "git/si/actions"
2
8
  require "thor"
3
9
  require "pager"
4
10
 
@@ -6,41 +12,37 @@ module Git
6
12
 
7
13
  module Si
8
14
 
9
- class GitSiError < StandardError
10
- end
11
-
12
- class ShellError < GitSiError
13
- end
14
-
15
- class GitError < GitSiError
16
- end
17
-
18
- class SvnError < GitSiError
19
- end
20
-
21
- class VersionError < GitSiError
22
- end
23
-
24
15
  class SvnInterface < Thor
25
16
  include Thor::Actions
26
17
  include Pager
18
+ include Git::Si::Util
19
+ include Git::Si::Actions
27
20
 
28
- default_task :usage
21
+ class_option :debug, :type => :boolean, :desc => 'Print lots of output', :default => false
22
+ class_option :quiet, :type => :boolean, :desc => 'Print only the minimum output', :default => false
23
+ class_option :svn, :type => :string, :desc => 'The path to the svn binary', :default => 'svn'
24
+ class_option :git, :type => :string, :desc => 'The path to the git binary', :default => 'git'
29
25
 
30
- @@mirror_branch = 'MIRRORBRANCH'
26
+ default_task :usage
31
27
 
28
+ ################
29
+ # Action: version
30
+ ################
32
31
  desc "version", "Print the version."
33
32
  def version
34
- say "git-si version #{Git::Si::VERSION}"
33
+ say Git::Si::Version.version_string
35
34
  end
36
35
 
36
+ ################
37
+ # Action: usage
38
+ ################
37
39
  desc "usage", "How does this thing work?"
38
40
  def usage
39
- say "git-si #{Git::Si::VERSION}
41
+ say "#{Git::Si::Version.version_string}
40
42
 
41
43
  Git Svn Interface: a simple git extention to use git locally with a remote svn
42
- repo. It's like a simple version of git-svn which doesn't keep track of history
43
- locally.
44
+ repository. It's like a simple version of git-svn just for using local
45
+ branching. It does not keep track of the full history of the svn repository.
44
46
 
45
47
  Start with the init command to set up the mirror branch and from there you can
46
48
  use the commands below.
@@ -49,387 +51,84 @@ use the commands below.
49
51
  help
50
52
  end
51
53
 
54
+ ################
55
+ # Action: status
56
+ ################
52
57
  desc "status [FILES]", "Perform an svn status."
53
58
  def status(*args)
54
- on_local_branch do
55
- command = "svn status --ignore-externals " + args.join(' ')
56
- svn_status = `#{command}`
57
- raise SvnError.new("Failed to get the svn status. I'm not sure why. Check for any errors above.") if ! $?.success?
58
- svn_status.each_line do |line|
59
- case line.strip!
60
- when /^X/, /\.git/, /\.swp$/
61
- else
62
- if STDOUT.tty?
63
- print_colordiff line
64
- else
65
- say line
66
- end
67
- end
68
- end
69
- end
59
+ configure
60
+ do_status_action( args )
70
61
  end
71
62
 
63
+ ################
64
+ # Action: diff
65
+ ################
72
66
  desc "diff [FILES]", "Perform an svn diff piped through a colorizer. Also tests to be sure a rebase is not needed."
73
67
  def diff(*args)
74
- on_local_branch do
75
- last_fetched_version = get_svn_version()
76
- git_log = `git log --pretty=%B`
77
- results = git_log.match(/svn update to version (\d+)/i)
78
- last_rebased_version = results[1] if results
79
- if last_fetched_version and last_rebased_version
80
- if last_fetched_version > last_rebased_version
81
- raise VersionError.new("This branch is out-of-date (rev #{last_rebased_version}; mirror branch is at #{last_fetched_version}). You should do a git si rebase.")
82
- elsif last_fetched_version < last_rebased_version
83
- return if ask("This branch is newer (rev #{last_rebased_version}) than the mirror branch (rev #{last_fetched_version}). That can happen when svn changes have been made directly and may be fine. Do you want to continue? [Y/n] ", :green) =~ /\s*^n/i
84
- end
85
- else
86
- notice_message "Could not determine last version information. This may be fine if you haven't used git-si before."
87
- end
88
-
89
- notice_message "Adding any files that are not already in svn to ensure an accurate diff."
90
- readd()
91
-
92
- command = "svn diff " + args.join(' ')
93
- notice_message "Running #{command}"
94
- results = `#{command}`
95
- if STDOUT.tty?
96
- page
97
- print_colordiff results
98
- else
99
- say results
100
- end
101
- end
68
+ configure
69
+ do_diff_action( args )
102
70
  end
103
71
 
72
+ ################
73
+ # Action: add
74
+ ################
104
75
  desc "add [FILES]", "Perform an svn and a git add on the files."
105
76
  def add(*args)
106
- on_local_branch do
107
- command = "svn add " + args.join(' ')
108
- run_command(command)
109
- command = "git add " + args.join(' ')
110
- run_command(command)
111
- end
77
+ configure
78
+ do_add_action( args )
112
79
  end
113
80
 
81
+ ################
82
+ # Action: fetch
83
+ ################
114
84
  desc "fetch", "Updates mirror branch to latest svn commit."
115
85
  def fetch
116
- on_local_branch do
117
- git_status = `git status --porcelain`
118
- raise GitError.new("There are local changes; please commit them before continuing.") if git_status.match(/^[^\?]/)
119
- end
120
- on_mirror_branch do
121
- notice_message "Fetching remote data from svn"
122
- updated_files = `svn up --accept theirs-full --ignore-externals`
123
- files_to_add = []
124
- updated_files.each_line do |line|
125
- say line
126
- case line.strip!
127
- when /^A\s+(\S.+)/, /^Restored '(.+)'\s*$/
128
- files_to_add << '"' + $1 + '"'
129
- end
130
- end
131
- notice_message "Reverting any local changes in mirror branch"
132
- run_command("svn revert -R ./")
133
- unless files_to_add.empty?
134
- files_to_add.each do |filename|
135
- say "Updating file in git: #{filename}"
136
- end
137
- notice_message "Adding all those files"
138
- system("git add --all " + files_to_add.join(' '))
139
- end
140
- run_command("git commit --allow-empty -am 'svn update to version #{get_svn_version}'")
141
- end
142
- success_message "fetch complete!"
86
+ configure
87
+ do_fetch_action
143
88
  end
144
89
 
90
+ ################
91
+ # Action: rebase
92
+ ################
145
93
  desc "rebase", "Rebases current branch to mirror branch."
146
94
  def rebase
147
- on_local_branch do
148
- run_command("git rebase '#{@@mirror_branch}'")
149
- success_message "rebase complete!"
150
- end
95
+ configure
96
+ do_rebase_action
151
97
  end
152
98
 
99
+ ################
100
+ # Action: pull
101
+ ################
153
102
  desc "pull", "Fetch the latest svn commit and rebase the current branch."
154
103
  def pull
155
- fetch
156
- rebase
104
+ do_pull_action
157
105
  end
158
106
 
107
+ ################
108
+ # Action: commit
109
+ ################
159
110
  desc "commit", "Perform an svn commit and update the mirror branch."
160
111
  def commit
161
- mirror_is_updated = false
162
-
163
- on_local_branch do
164
- local_branch = get_local_branch()
165
- if local_branch == 'master'
166
- notice_message "Warning: you're using the master branch as working copy. This can
167
- cause trouble because when your changes are committed and you try to
168
- rebase on top of them, you may end up with merge errors as you are
169
- trying to apply patches of previous versions of your code. If you
170
- continue, it's wise to reset the master branch afterward."
171
- return if ask("Do you want to continue with this commit? [Y/n] ", :green) =~ /\s*^n/i
172
- end
173
-
174
- git_status = `git status --porcelain`
175
- raise GitError.new("There are local changes; please commit them before continuing.") if git_status.match(/^[^\?]/)
176
-
177
- notice_message "Adding any files that are not already in svn to ensure changes are committed."
178
- readd()
179
-
180
- svn_diff = `svn diff`
181
- raise SvnError.new("Failed to get the svn diff. I'm not sure why. Check for any errors above.") if ! $?.success?
182
- raise SvnError.new("There are no changes to commit.") if svn_diff.strip.empty?
183
-
184
- run_command("svn commit")
185
- success_message "commit complete!"
186
-
187
- files_unchanged = true
188
- git_status = `git status --porcelain`
189
- files_unchanged = false if git_status.match(/^[^\?]/)
190
- unless files_unchanged
191
- if yes? "Some files were added or modified during the commit; should I revert them? [y/N] ", :yellow
192
- run_command("git reset --hard HEAD")
193
- files_unchanged = true
194
- end
195
- end
196
-
197
- if files_unchanged and yes? "Do you want to update the mirror branch to the latest commit? [y/N] ", :green
198
- fetch
199
- mirror_is_updated = true
200
- end
201
- end
202
-
203
- if mirror_is_updated
204
- local_branch = get_local_branch()
205
- if local_branch == 'master'
206
- if yes? "Do you want to reset the current branch to the latest commit (losing all git history)? [y/N] ", :green
207
- run_command("git checkout #{@@mirror_branch}")
208
- run_command("git branch -D '#{local_branch}'")
209
- run_command("git checkout -b #{local_branch}")
210
- success_message "branch '#{local_branch}' reset!"
211
- end
212
- else
213
- if yes? "Do you want to switch to master and delete the committed branch '#{local_branch}'? [y/N] ", :green
214
- run_command("git checkout master")
215
- rebase
216
- run_command("git branch -D '#{local_branch}'")
217
- success_message "branch '#{local_branch}' deleted!"
218
- end
219
- end
220
- end
112
+ configure
113
+ do_commit_action
221
114
  end
222
115
 
116
+ ################
117
+ # Action: readd
118
+ ################
223
119
  desc "readd", "Add files to svn that have been added to git."
224
- def readd()
225
- on_local_branch do
226
- command = "svn status --ignore-externals"
227
- svn_status = `#{command}`
228
- raise SvnError.new("Failed to get the svn status. I'm not sure why. Check for any errors above.") if ! $?.success?
229
- files_to_add = []
230
- using_stderr do
231
- svn_status.each_line do |line|
232
- case line.strip!
233
- when /^X/, /\.git/, /\.swp$/
234
- when /^\?\s+(\S.+)/
235
- filename = $1
236
- file_in_git = `git ls-files #{filename}`
237
- raise GitError.new("Failed to list git files. I'm not sure why. Check for any errors above.") unless $?.success?
238
- if not file_in_git.empty?
239
- files_to_add << filename if file_in_git
240
- say filename
241
- end
242
- end
243
- end
244
- end
245
- if files_to_add.empty?
246
- notice_message "There are no files to add."
247
- return
248
- end
249
- using_stderr do
250
- if yes? "Do you want to add the above files to svn? [y/N] ", :green
251
- command = "svn add " + files_to_add.join(' ')
252
- run_command(command)
253
- success_message "Added files to svn that had been added to git."
254
- end
255
- end
256
- end
257
- end
258
-
259
- desc "blame <FILE>", "Alias for svn blame."
260
- def blame(*args)
261
- on_local_branch do
262
- command = "svn blame " + args.join(' ')
263
- run_command(command)
264
- end
120
+ def readd
121
+ configure
122
+ do_readd_action
265
123
  end
266
124
 
125
+ ################
126
+ # Action: init
127
+ ################
267
128
  desc "init", "Initializes git-si in this directory with a gitignore and creates a special mirror branch."
268
129
  def init
269
- on_local_branch do
270
- # check for svn repo
271
- `svn info`
272
- raise SvnError.new("No svn repository was found here. Maybe you're in the wrong directory?") unless $?.success?
273
- make_a_commit = false
274
-
275
- # check for existing .git repo
276
- if File.exist? '.git'
277
- notice_message "Looks like a git repository already exists here."
278
- else
279
- notice_message "Initializing git repository"
280
- `git init`
281
- raise GitError.new("Failed to initialize git repository. I'm not sure why. Check for any errors above.") unless $?.success?
282
- make_a_commit = true
283
- end
284
-
285
- # check for existing .gitingore
286
- gitignore = [".svn", "*.sw?", ".config", "*.err", "*.pid", "*.log", "svn-commit.*", "*.orig"]
287
- command = "svn status --ignore-externals "
288
- svn_status = `#{command}`
289
- raise SvnError.new("Failed to get the svn status. I'm not sure why. Check for any errors above.") if ! $?.success?
290
- externals = []
291
- svn_status.each_line do |line|
292
- externals << $1 if line.strip.match(/^X\s+(\S.+)/)
293
- end
294
- gitignore += externals
295
- gitignore = gitignore.join("\n")
296
-
297
- if File.exist? '.gitignore'
298
- notice_message "Looks like a gitignore file already exists here."
299
- error_message "Be SURE that the gitignore contains the following:\n#{gitignore}"
300
- else
301
- notice_message "Creating gitignore file."
302
- create_file('.gitignore', gitignore)
303
- run_command("git add .gitignore")
304
- make_a_commit = true
305
- end
306
-
307
- # make initial commit
308
- if make_a_commit
309
- notice_message "Making initial commit."
310
- run_command("git add .")
311
- run_command("git commit -am 'initial commit by git-si'")
312
- end
313
-
314
- # check for exiting mirror branch
315
- `git show-ref refs/heads/#{@@mirror_branch}`
316
- if $?.success?
317
- notice_message "Looks like the mirror branch already exists here."
318
- else
319
- notice_message "Creating mirror branch '#{@@mirror_branch}'."
320
- run_command("git branch '#{@@mirror_branch}'")
321
- end
322
-
323
- success_message "init complete!"
324
- end
325
- end
326
-
327
-
328
- private
329
-
330
- def get_svn_version
331
- svn_info = `svn info`
332
- results = svn_info.match(/^Revision:\s+(\d+)/)
333
- return results[1] if results
334
- return nil
335
- end
336
-
337
- def get_svn_root
338
- svn_info = `svn info`
339
- results = svn_info.match(/Root Path:\s+(.+)/)
340
- return results[1] if results
341
- return nil
342
- end
343
-
344
- def get_local_branch
345
- git_branches = `git branch`
346
- results = git_branches.match(/^\*\s+(\S+)/)
347
- local_branch = results[1] if results
348
- raise GitError.new("Could not find local branch name.") unless local_branch
349
- return local_branch
350
- end
351
-
352
- def in_svn_root(&block)
353
- root_dir = get_svn_root
354
- raise SvnError.new("Could not find the svn root directory.") unless root_dir
355
- notice_message "Changing directory to svn root: #{root_dir}"
356
- Dir.chdir(root_dir) do
357
- yield
358
- end
359
- end
360
-
361
- def on_local_branch(&block)
362
- begin
363
- in_svn_root do
364
- yield
365
- end
366
- rescue GitSiError => err
367
- error_message err
368
- exit false
369
- end
370
- end
371
-
372
- def on_mirror_branch(&block)
373
- local_branch = get_local_branch()
374
- run_command("git checkout #{@@mirror_branch}")
375
- begin
376
- in_svn_root do
377
- yield
378
- end
379
- rescue GitSiError => err
380
- error_message err
381
- exit false
382
- ensure
383
- run_command("git checkout #{local_branch}")
384
- end
385
- end
386
-
387
- def using_stderr(&block)
388
- old_stdout = $stdout
389
- $stdout = $stderr
390
- @silent = true
391
- begin
392
- yield
393
- ensure
394
- $stdout = old_stdout
395
- @silent = false
396
- end
397
- end
398
-
399
- def success_message(message)
400
- $stderr.puts set_color message, :green
401
- end
402
-
403
- def notice_message(message)
404
- $stderr.puts set_color message, :yellow
405
- end
406
-
407
- def error_message(message)
408
- $stderr.puts set_color message, :red
409
- end
410
-
411
- def run_command(command, options={})
412
- if STDOUT.tty? and not @silent
413
- run(command, options)
414
- else
415
- run(command, options.update(verbose: false, capture: true))
416
- end
417
- raise ShellError.new("There was an error while trying to run the command: #{command}. Look above for any errors.") unless $?.success?
418
- end
419
-
420
- def print_colordiff(diff)
421
- diff.each_line do |line|
422
- line.rstrip!
423
- case line
424
- when /^\+/, /^A/
425
- line = set_color line, :green
426
- when /^\-/, /^M/
427
- line = set_color line, :red
428
- when /^\?/
429
- line = set_color line, :yellow
430
- end
431
- say line
432
- end
130
+ configure
131
+ do_init_action
433
132
  end
434
133
 
435
134
  end