git-process 1.1.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGELOG.md +14 -1
  2. data/LICENSE +193 -22
  3. data/README.md +212 -71
  4. data/man/git-process.1 +371 -0
  5. metadata +52 -140
  6. data/Gemfile +0 -20
  7. data/Gemfile.lock +0 -53
  8. data/Rakefile +0 -16
  9. data/bin/git-new-fb +0 -58
  10. data/bin/git-pull-request +0 -107
  11. data/bin/git-sync +0 -73
  12. data/bin/git-to-master +0 -133
  13. data/git-process.gemspec +0 -25
  14. data/lib/git-process/abstract_error_builder.rb +0 -53
  15. data/lib/git-process/changed_file_helper.rb +0 -115
  16. data/lib/git-process/git_abstract_merge_error_builder.rb +0 -146
  17. data/lib/git-process/git_branch.rb +0 -105
  18. data/lib/git-process/git_branches.rb +0 -73
  19. data/lib/git-process/git_config.rb +0 -153
  20. data/lib/git-process/git_lib.rb +0 -512
  21. data/lib/git-process/git_logger.rb +0 -84
  22. data/lib/git-process/git_merge_error.rb +0 -28
  23. data/lib/git-process/git_process.rb +0 -172
  24. data/lib/git-process/git_process_error.rb +0 -18
  25. data/lib/git-process/git_process_options.rb +0 -99
  26. data/lib/git-process/git_rebase_error.rb +0 -30
  27. data/lib/git-process/git_remote.rb +0 -256
  28. data/lib/git-process/git_status.rb +0 -108
  29. data/lib/git-process/github_configuration.rb +0 -298
  30. data/lib/git-process/github_pull_request.rb +0 -151
  31. data/lib/git-process/new_fb.rb +0 -50
  32. data/lib/git-process/parked_changes_error.rb +0 -41
  33. data/lib/git-process/pull_request.rb +0 -134
  34. data/lib/git-process/pull_request_error.rb +0 -25
  35. data/lib/git-process/rebase_to_master.rb +0 -148
  36. data/lib/git-process/sync.rb +0 -136
  37. data/lib/git-process/uncommitted_changes_error.rb +0 -23
  38. data/lib/git-process/version.rb +0 -22
  39. data/spec/FileHelpers.rb +0 -19
  40. data/spec/GitRepoHelper.rb +0 -123
  41. data/spec/changed_file_helper_spec.rb +0 -127
  42. data/spec/git_abstract_merge_error_builder_spec.rb +0 -126
  43. data/spec/git_branch_spec.rb +0 -123
  44. data/spec/git_config_spec.rb +0 -45
  45. data/spec/git_lib_spec.rb +0 -176
  46. data/spec/git_logger_spec.rb +0 -66
  47. data/spec/git_process_spec.rb +0 -208
  48. data/spec/git_remote_spec.rb +0 -227
  49. data/spec/git_status_spec.rb +0 -122
  50. data/spec/github_configuration_spec.rb +0 -152
  51. data/spec/github_pull_request_spec.rb +0 -96
  52. data/spec/github_test_helper.rb +0 -49
  53. data/spec/new_fb_spec.rb +0 -130
  54. data/spec/pull_request_helper.rb +0 -94
  55. data/spec/pull_request_spec.rb +0 -128
  56. data/spec/rebase_to_master_spec.rb +0 -429
  57. data/spec/spec_helper.rb +0 -21
  58. data/spec/sync_spec.rb +0 -304
@@ -1,73 +0,0 @@
1
- # Licensed under the Apache License, Version 2.0 (the "License");
2
- # you may not use this file except in compliance with the License.
3
- # You may obtain a copy of the License at
4
- #
5
- # http://www.apache.org/licenses/LICENSE-2.0
6
- #
7
- # Unless required by applicable law or agreed to in writing, software
8
- # distributed under the License is distributed on an "AS IS" BASIS,
9
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- # See the License for the specific language governing permissions and
11
- # limitations under the License.
12
-
13
- require 'set'
14
- require 'git-process/git_branch'
15
-
16
- module GitProc
17
-
18
- class GitBranches
19
- include Enumerable
20
-
21
-
22
- def initialize(lib)
23
- @lib = lib
24
- branch_lines = lib.branch(nil, :all => true, :no_color => true).split("\n")
25
- @items = SortedSet.new
26
- branch_lines.each do |bl|
27
- @items << GitBranch.new(bl[2..-1], bl[0..0] == '*', lib)
28
- end
29
- end
30
-
31
-
32
- def <<(item)
33
- @items << item
34
- end
35
-
36
-
37
- def each(&block)
38
- @items.each { |b| block.call(b) }
39
- end
40
-
41
-
42
- def names
43
- @items.map { |b| b.name }
44
- end
45
-
46
-
47
- def current
48
- @items.find { |b| b.current? }
49
- end
50
-
51
-
52
- def parking
53
- @items.find { |b| b.name == '_parking_' }
54
- end
55
-
56
-
57
- def include?(branch_name)
58
- @items.find { |b| b.name == branch_name } != nil
59
- end
60
-
61
-
62
- def [](branch_name)
63
- branch_name = current.name if branch_name == 'HEAD'
64
- br = @items.find { |b| b.name == branch_name }
65
- if br.nil? and branch_name !~ /origin\// and branch_name != '_parking_'
66
- @lib.logger.warn { "Could not find '#{branch_name}' in #{@items.map { |i| i.name }.join(',')}" }
67
- end
68
- br
69
- end
70
-
71
- end
72
-
73
- end
@@ -1,153 +0,0 @@
1
- # Licensed under the Apache License, Version 2.0 (the "License");
2
- # you may not use this file except in compliance with the License.
3
- # You may obtain a copy of the License at
4
- #
5
- # http://www.apache.org/licenses/LICENSE-2.0
6
- #
7
- # Unless required by applicable law or agreed to in writing, software
8
- # distributed under the License is distributed on an "AS IS" BASIS,
9
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- # See the License for the specific language governing permissions and
11
- # limitations under the License.
12
-
13
- require 'git-process/git_logger'
14
- require 'git-process/git_branch'
15
- require 'git-process/git_branches'
16
- require 'git-process/git_status'
17
- require 'git-process/git_process_error'
18
-
19
-
20
- class String
21
-
22
- def to_boolean
23
- return false if self == false || self.nil? || self =~ (/(false|f|no|n|0)$/i)
24
- return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
25
- raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
26
- end
27
-
28
- end
29
-
30
-
31
- class NilClass
32
- def to_boolean
33
- false
34
- end
35
- end
36
-
37
-
38
- module GitProc
39
-
40
- #
41
- # Provides Git configuration
42
- #
43
- class GitConfig
44
-
45
- def initialize(lib)
46
- @lib = lib
47
- end
48
-
49
-
50
- def [](key)
51
- value = config_hash[key]
52
- unless value
53
- value = @lib.command(:config, ['--get', key])
54
- value = nil if value.empty?
55
- config_hash[key] = value unless config_hash.empty?
56
- end
57
- value
58
- end
59
-
60
-
61
- def []=(key, value)
62
- @lib.command(:config, [key, value])
63
- config_hash[key] = value unless config_hash.empty?
64
- value
65
- end
66
-
67
-
68
- def set_global(key, value)
69
- @lib.command(:config, ['--global', key, value])
70
- config_hash[key] = value unless config_hash.empty?
71
- value
72
- end
73
-
74
-
75
- def gitlib
76
- @lib
77
- end
78
-
79
-
80
- def logger
81
- gitlib.logger
82
- end
83
-
84
-
85
- def master_branch
86
- @master_branch ||= self['gitProcess.integrationBranch'] || 'master'
87
- end
88
-
89
-
90
- def remote_master_branch
91
- remote.master_branch_name
92
- end
93
-
94
-
95
- def integration_branch
96
- remote.exists? ? remote_master_branch : self.master_branch
97
- end
98
-
99
-
100
- def rerere_enabled?
101
- re = self['rerere.enabled']
102
- re && re.to_boolean
103
- end
104
-
105
-
106
- def rerere_enabled(re, global = true)
107
- if global
108
- set_global('rerere.enabled', re)
109
- else
110
- self['rerere.enabled'] = re
111
- end
112
- end
113
-
114
-
115
- def rerere_enabled=(re)
116
- rerere_enabled(re, false)
117
- end
118
-
119
-
120
- def rerere_autoupdate?
121
- re = self['rerere.autoupdate']
122
- re && re.to_boolean
123
- end
124
-
125
-
126
- def rerere_autoupdate(re, global = true)
127
- if global
128
- set_global('rerere.autoupdate', re)
129
- else
130
- self['rerere.autoupdate'] = re
131
- end
132
- end
133
-
134
-
135
- def rerere_autoupdate=(re)
136
- rerere_autoupdate(re, false)
137
- end
138
-
139
-
140
- private
141
-
142
- def remote
143
- gitlib.remote
144
- end
145
-
146
-
147
- def config_hash
148
- @config_hash ||= {}
149
- end
150
-
151
- end
152
-
153
- end
@@ -1,512 +0,0 @@
1
- # Licensed under the Apache License, Version 2.0 (the "License");
2
- # you may not use this file except in compliance with the License.
3
- # You may obtain a copy of the License at
4
- #
5
- # http://www.apache.org/licenses/LICENSE-2.0
6
- #
7
- # Unless required by applicable law or agreed to in writing, software
8
- # distributed under the License is distributed on an "AS IS" BASIS,
9
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- # See the License for the specific language governing permissions and
11
- # limitations under the License.
12
-
13
- require 'logger'
14
- require 'git-process/git_branch'
15
- require 'git-process/git_branches'
16
- require 'git-process/git_remote'
17
- require 'git-process/git_status'
18
- require 'git-process/git_process_error'
19
-
20
-
21
- module GitProc
22
-
23
- class GitExecuteError < GitProcessError
24
- end
25
-
26
-
27
- #
28
- # Provides Git commands
29
- #
30
- #noinspection RubyTooManyMethodsInspection
31
- class GitLib
32
-
33
- # @param [Dir] dir
34
- def initialize(dir, opts)
35
- self.log_level = GitLib.log_level(opts)
36
- self.workdir = dir
37
- end
38
-
39
-
40
- def logger
41
- if @logger.nil?
42
- @logger = GitLogger.new(log_level)
43
- end
44
- @logger
45
- end
46
-
47
-
48
- def self.log_level(opts)
49
- if opts[:log_level]
50
- opts[:log_level]
51
- elsif opts[:quiet]
52
- Logger::ERROR
53
- elsif opts[:verbose]
54
- Logger::DEBUG
55
- else
56
- Logger::INFO
57
- end
58
- end
59
-
60
-
61
- def log_level
62
- @log_level || Logger::WARN
63
- end
64
-
65
-
66
- def log_level=(lvl)
67
- @log_level = lvl
68
- end
69
-
70
-
71
- def workdir
72
- @workdir
73
- end
74
-
75
-
76
- def workdir=(dir)
77
- workdir = GitLib.find_workdir(dir)
78
- if workdir.nil?
79
- @workdir = dir
80
- logger.info { "Initializing new repository at #{dir}" }
81
- command(:init)
82
- else
83
- @workdir = workdir
84
- logger.debug { "Opening existing repository at #{dir}" }
85
- end
86
- end
87
-
88
-
89
- def self.find_workdir(dir)
90
- if dir == File::SEPARATOR
91
- nil
92
- elsif File.directory?(File.join(dir, '.git'))
93
- dir
94
- else
95
- find_workdir(File.expand_path("#{dir}#{File::SEPARATOR}.."))
96
- end
97
- end
98
-
99
-
100
- def config
101
- if @config.nil?
102
- @config = GitConfig.new(self)
103
- end
104
- @config
105
- end
106
-
107
-
108
- def remote
109
- if @remote.nil?
110
- @remote = GitProc::GitRemote.new(config)
111
- end
112
- @remote
113
- end
114
-
115
-
116
- # @return [Boolean] does this have a remote defined?
117
- def has_a_remote?
118
- remote.exists?
119
- end
120
-
121
-
122
- def add(file)
123
- logger.info { "Adding #{[*file].join(', ')}" }
124
- command(:add, ['--', file])
125
- end
126
-
127
-
128
- def commit(msg = nil)
129
- logger.info 'Committing changes'
130
- command(:commit, msg.nil? ? nil : ['-m', msg])
131
- end
132
-
133
-
134
- def rebase(base, opts = {})
135
- args = []
136
- if opts[:interactive]
137
- logger.info { "Interactively rebasing #{branches.current.name} against #{base}" }
138
- args << '-i'
139
- else
140
- logger.info { "Rebasing #{branches.current.name} against #{base}" }
141
- end
142
- args << base
143
- command('rebase', args)
144
- end
145
-
146
-
147
- def merge(base)
148
- logger.info { "Merging #{branches.current.name} with #{base}" }
149
- command(:merge, [base])
150
- end
151
-
152
-
153
- def fetch(name = remote.name)
154
- logger.info 'Fetching the latest changes from the server'
155
- output = self.command(:fetch, ['-p', name])
156
-
157
- log_fetch_changes(fetch_changes(output))
158
-
159
- output
160
- end
161
-
162
-
163
- # @param [Hash] changes a hash of the changes that were made
164
- #
165
- # @return [void]
166
- def log_fetch_changes(changes)
167
- changes.each do |key, v|
168
- unless v.empty?
169
- logger.info { " #{key.to_s.sub(/_/, ' ')}: #{v.join(', ')}" }
170
- end
171
- end
172
- end
173
-
174
-
175
- # @return [Hash]
176
- def fetch_changes(output)
177
- changed = output.split("\n")
178
-
179
- changes = {:new_branch => [], :new_tag => [], :force_updated => [], :deleted => [], :updated => []}
180
-
181
- line = changed.shift
182
-
183
- until line.nil? do
184
- case line
185
- when /^\s\s\s/
186
- m = /^\s\s\s(\S+)\s+(\S+)\s/.match(line)
187
- changes[:updated] << "#{m[2]} (#{m[1]})"
188
- when /^\s\*\s\[new branch\]/
189
- m = /^\s\*\s\[new branch\]\s+(\S+)\s/.match(line)
190
- changes[:new_branch] << m[1]
191
- when /^\s\*\s\[new tag\]/
192
- m = /^\s\*\s\[new tag\]\s+(\S+)\s/.match(line)
193
- changes[:new_tag] << m[1]
194
- when /^\sx\s/
195
- m = /^\sx\s\[deleted\]\s+\(none\)\s+->\s+[^\/]+\/(\S+)/.match(line)
196
- changes[:deleted] << m[1]
197
- when /^\s\+\s/
198
- m = /^\s\+\s(\S+)\s+(\S+)\s/.match(line)
199
- changes[:force_updated] << "#{m[2]} (#{m[1]})"
200
- else
201
- # ignore the line
202
- end
203
- line = changed.shift
204
- end
205
-
206
- changes
207
- end
208
-
209
-
210
- def branches
211
- GitProc::GitBranches.new(self)
212
- end
213
-
214
-
215
- #
216
- # Does branch manipulation.
217
- #
218
- # @param [String] branch_name the name of the branch
219
- #
220
- # @option opts [Boolean] :delete delete the remote branch
221
- # @option opts [Boolean] :force force the update
222
- # @option opts [Boolean] :all list all branches, local and remote
223
- # @option opts [Boolean] :no_color force not using any ANSI color codes
224
- # @option opts [String] :rename the new name for the branch
225
- # @option opts [String] :upstream the new branch to track
226
- # @option opts [String] :base_branch the branch to base the new branch off of;
227
- # defaults to 'master'
228
- #
229
- # @return [String] the output of running the git command
230
- def branch(branch_name, opts = {})
231
- if opts[:delete]
232
- delete_branch(branch_name, opts[:force])
233
- elsif opts[:rename]
234
- rename_branch(branch_name, opts[:rename])
235
- elsif opts[:upstream]
236
- set_upstream_branch(branch_name, opts[:upstream])
237
- elsif branch_name
238
- if opts[:force]
239
- change_branch(branch_name, opts[:base_branch])
240
- else
241
- create_branch(branch_name, opts[:base_branch])
242
- end
243
- else
244
- list_branches(opts[:all], opts[:no_color])
245
- end
246
- end
247
-
248
-
249
- #
250
- # Pushes the given branch to the server.
251
- #
252
- # @param [String] remote_name the repository name; nil -> 'origin'
253
- # @param [String] local_branch the local branch to push; nil -> the current branch
254
- # @param [String] remote_branch the name of the branch to push to; nil -> same as local_branch
255
- #
256
- # @option opts [Boolean, String] :delete delete the remote branch
257
- # @option opts [Boolean] :force force the update, even if not a fast-forward
258
- #
259
- # @return [void]
260
- #
261
- # @raise [ArgumentError] if :delete is true, but no branch name is given
262
- def push(remote_name, local_branch, remote_branch, opts = {})
263
- remote_name ||= 'origin'
264
-
265
- args = [remote_name]
266
-
267
- if opts[:delete]
268
- if remote_branch
269
- rb = remote_branch
270
- elsif local_branch
271
- rb = local_branch
272
- elsif !(opts[:delete].is_a? TrueClass)
273
- rb = opts[:delete]
274
- else
275
- raise ArgumentError.new('Need a branch name to delete.')
276
- end
277
-
278
- int_branch = config.master_branch
279
- if rb == int_branch
280
- raise GitProc::GitProcessError.new("Can not delete the integration branch '#{int_branch}'")
281
- end
282
-
283
- logger.info { "Deleting remote branch '#{rb}' on '#{remote_name}'." }
284
- args << '--delete' << rb
285
- else
286
- local_branch ||= branches.current
287
- remote_branch ||= local_branch
288
- args << '-f' if opts[:force]
289
-
290
- logger.info do
291
- if local_branch == remote_branch
292
- "Pushing to '#{remote_branch}' on '#{remote_name}'."
293
- else
294
- "Pushing #{local_branch} to '#{remote_branch}' on '#{remote_name}'."
295
- end
296
- end
297
-
298
- args << "#{local_branch}:#{remote_branch}"
299
- end
300
- command(:push, args)
301
- end
302
-
303
-
304
- def rebase_continue
305
- command(:rebase, '--continue')
306
- end
307
-
308
-
309
- def stash_save
310
- command(:stash, %w(save))
311
- end
312
-
313
-
314
- def stash_pop
315
- command(:stash, %w(pop))
316
- end
317
-
318
-
319
- def show(refspec)
320
- command(:show, refspec)
321
- end
322
-
323
-
324
- def checkout(branch_name, opts = {})
325
- args = []
326
- args << '--no-track' if opts[:no_track]
327
- args << '-b' if opts[:new_branch]
328
- args << branch_name
329
- args << opts[:new_branch] if opts[:new_branch]
330
- branches = branches()
331
- command(:checkout, args)
332
-
333
- branches << GitBranch.new(branch_name, opts[:new_branch] != nil, self)
334
-
335
- if block_given?
336
- yield
337
- command(:checkout, branches.current.name)
338
- branches.current
339
- else
340
- branches[branch_name]
341
- end
342
- end
343
-
344
-
345
- def log_count
346
- command(:log, '--oneline').split(/\n/).length
347
- end
348
-
349
-
350
- def remove(files, opts = {})
351
- args = []
352
- args << '-f' if opts[:force]
353
- args << [*files]
354
- command(:rm, args)
355
- end
356
-
357
-
358
- #
359
- # Returns the status of the git repository.
360
- #
361
- # @return [Status]
362
- def status
363
- GitStatus.new(self)
364
- end
365
-
366
-
367
- # @return [String] the raw porcelain status string
368
- def porcelain_status
369
- command(:status, '--porcelain')
370
- end
371
-
372
-
373
- def reset(rev_name, opts = {})
374
- args = []
375
- args << '--hard' if opts[:hard]
376
- args << rev_name
377
-
378
- logger.info { "Resetting #{opts[:hard] ? '(hard)' : ''} to #{rev_name}" }
379
-
380
- command(:reset, args)
381
- end
382
-
383
-
384
- def rev_list(start_revision, end_revision, opts ={})
385
- args = []
386
- args << "-#{opts[:num_revs]}" if opts[:num_revs]
387
- args << '--oneline' if opts[:oneline]
388
- args << "#{start_revision}..#{end_revision}"
389
- command('rev-list', args)
390
- end
391
-
392
-
393
- def rev_parse(name)
394
- command('rev-parse', name)
395
- end
396
-
397
-
398
- alias sha rev_parse
399
-
400
-
401
- # @return [String]
402
- def command(cmd, opts = [], chdir = true, redirect = '', &block)
403
- ENV['GIT_INDEX_FILE'] = File.join(workdir, '.git', 'index')
404
- ENV['GIT_DIR'] = File.join(workdir, '.git')
405
- ENV['GIT_WORK_TREE'] = workdir
406
- path = workdir
407
-
408
- git_cmd = create_git_command(cmd, opts, redirect)
409
-
410
- out = command_git_cmd(path, git_cmd, chdir, block)
411
-
412
- if logger
413
- logger.debug(git_cmd)
414
- logger.debug(out)
415
- end
416
-
417
- handle_exitstatus($?, git_cmd, out)
418
- end
419
-
420
-
421
- private
422
-
423
-
424
- def create_git_command(cmd, opts, redirect)
425
- opts = [opts].flatten.map { |s| escape(s) }.join(' ')
426
- "git #{cmd} #{opts} #{redirect} 2>&1"
427
- end
428
-
429
-
430
- def command_git_cmd(path, git_cmd, chdir, block)
431
- out = nil
432
- if chdir and (Dir.getwd != path)
433
- Dir.chdir(path) { out = run_command(git_cmd, &block) }
434
- else
435
- out = run_command(git_cmd, &block)
436
- end
437
- out
438
- end
439
-
440
-
441
- # @return [String]
442
- def handle_exitstatus(proc_status, git_cmd, out)
443
- if proc_status.exitstatus > 0
444
- unless proc_status.exitstatus == 1 && out == ''
445
- raise GitProc::GitExecuteError.new(git_cmd + ':' + out.to_s)
446
- end
447
- end
448
- out
449
- end
450
-
451
-
452
- def run_command(git_cmd, &block)
453
- if block_given?
454
- IO.popen(git_cmd, &block)
455
- else
456
- `#{git_cmd}`.chomp
457
- end
458
- end
459
-
460
-
461
- def escape(s)
462
- escaped = s.to_s.gsub('\'', '\'\\\'\'')
463
- %Q{"#{escaped}"}
464
- end
465
-
466
-
467
- def change_branch(branch_name, base_branch)
468
- raise ArgumentError.new('Need :base_branch when using :force for a branch.') unless base_branch
469
- logger.info { "Changing branch '#{branch_name}' to point to '#{base_branch}'." }
470
-
471
- command(:branch, ['-f', branch_name, base_branch])
472
- end
473
-
474
-
475
- def create_branch(branch_name, base_branch)
476
- logger.info { "Creating new branch '#{branch_name}' based on '#{base_branch}'." }
477
-
478
- command(:branch, [branch_name, (base_branch || 'master')])
479
- end
480
-
481
-
482
- def list_branches(all_branches, no_color)
483
- args = []
484
- args << '-a' if all_branches
485
- args << '--no-color' if no_color
486
- command(:branch, args)
487
- end
488
-
489
-
490
- def delete_branch(branch_name, force)
491
- logger.info { "Deleting local branch '#{branch_name}'." } unless branch_name == '_parking_'
492
-
493
- command(:branch, [force ? '-D' : '-d', branch_name])
494
- end
495
-
496
-
497
- def rename_branch(branch_name, new_name)
498
- logger.info { "Renaming branch '#{branch_name}' to '#{new_name}'." }
499
-
500
- command(:branch, ['-m', branch_name, new_name])
501
- end
502
-
503
-
504
- def set_upstream_branch(branch_name, upstream)
505
- logger.info { "Setting upstream/tracking for branch '#{branch_name}' to '#{upstream}'." }
506
-
507
- command(:branch, ['--set-upstream-to', upstream, branch_name])
508
- end
509
-
510
- end
511
-
512
- end