git-topic 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --debug
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm 1.9.2-rc1
1
+ rvm 1.9.2
data/.vimproject CHANGED
@@ -8,7 +8,9 @@ project=$PWD cd=. {
8
8
  git-topic
9
9
  }
10
10
  lib=lib {
11
- git-topic.rb
11
+ git_topic=git_topic{
12
+ }
13
+ git_topic.rb
12
14
  util.rb
13
15
  }
14
16
  spec=spec {
data/Rakefile CHANGED
@@ -3,6 +3,15 @@ require 'rake'
3
3
 
4
4
  Dir[ 'lib/tasks/**/*' ].each{ |l| require l }
5
5
 
6
+ # TODO 1: cleanup specs (possibly have specs setup repos, or possibly tar up
7
+ # repos and extract them)
8
+ # TODO 2: topic abandon <topic>
9
+ # TODO 1: handle malformed args
10
+ # TODO 1: git-topic comment
11
+ # edit files & have the diffs pulled into notes?
12
+
13
+ # TODO 1: git work-on <topic> should kill review branch
14
+
6
15
 
7
16
  begin
8
17
  require 'jeweler'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.1.4
data/bin/git-topic CHANGED
@@ -2,7 +2,7 @@
2
2
  # encoding: utf-8
3
3
 
4
4
  require 'trollop'
5
- require 'git-topic'
5
+ require 'git_topic'
6
6
 
7
7
 
8
8
  module GitTopic
data/git-topic.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{git-topic}
8
- s.version = "0.1.3"
8
+ s.version = "0.1.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David J. Hamilton"]
12
- s.date = %q{2010-07-08}
12
+ s.date = %q{2010-07-13}
13
13
  s.default_executable = %q{git-topic}
14
14
  s.description = %q{
15
15
  gem command around reviewed topic branches. Supports workflow of the form:
@@ -57,9 +57,11 @@ Gem::Specification.new do |s|
57
57
  "autotest/discover.rb",
58
58
  "bin/git-topic",
59
59
  "git-topic.gemspec",
60
- "lib/git-topic.rb",
61
- "lib/util.rb",
62
- "spec/git-topic_spec.rb",
60
+ "lib/core_ext.rb",
61
+ "lib/git_topic.rb",
62
+ "lib/git_topic/git.rb",
63
+ "lib/git_topic/naming.rb",
64
+ "spec/git_topic_spec.rb",
63
65
  "spec/spec_helper.rb",
64
66
  "spec/template/origin/HEAD",
65
67
  "spec/template/origin/config",
@@ -102,7 +104,7 @@ Gem::Specification.new do |s|
102
104
  s.summary = %q{git command around reviewed topic branches}
103
105
  s.test_files = [
104
106
  "spec/spec_helper.rb",
105
- "spec/git-topic_spec.rb"
107
+ "spec/git_topic_spec.rb"
106
108
  ]
107
109
 
108
110
  if s.respond_to? :specification_version then
@@ -0,0 +1,58 @@
1
+
2
+ module GitTopic; end
3
+ module GitTopic::Git
4
+ module ClassMethods
5
+
6
+ protected
7
+
8
+ def working_tree_clean?
9
+ git [ "diff --quiet", "diff --quiet --cached" ]
10
+ $?.success?
11
+ end
12
+
13
+ def working_tree_dirty?
14
+ not working_tree_clean?
15
+ end
16
+
17
+
18
+ def display_git_output?
19
+ @@display_git_output ||= false
20
+ end
21
+
22
+ def display_git_output!
23
+ @@display_git_output = true
24
+ end
25
+
26
+
27
+ def switch_to_branch( branch, tracking=nil )
28
+ if branches.include?( branch )
29
+ "checkout #{branch}"
30
+ else
31
+ "checkout -b #{branch} #{tracking}"
32
+ end
33
+ end
34
+
35
+ def cmd_redirect_suffix( opts )
36
+ if !opts[:show] && !display_git_output?
37
+ "> /dev/null 2> /dev/null"
38
+ end
39
+ end
40
+
41
+ def git( cmds=[], opts={} )
42
+ cmds = [cmds] if cmds.is_a? String
43
+ redir = cmd_redirect_suffix( opts )
44
+ system cmds.map{|c| "git #{c} #{redir}"}.join( " && " )
45
+ end
46
+
47
+ def capture_git( cmds=[] )
48
+ cmds = [cmds] if cmds.is_a? String
49
+ redir = "2> /dev/null" unless display_git_output?
50
+ `#{cmds.map{|c| "git #{c} #{redir}"}.join( " && " )}`
51
+ end
52
+
53
+ end
54
+
55
+ def self.included( base )
56
+ base.extend ClassMethods
57
+ end
58
+ end
@@ -0,0 +1,150 @@
1
+
2
+ module GitTopic; end
3
+
4
+ module GitTopic::Naming
5
+ module ClassMethods
6
+
7
+ protected
8
+
9
+ def backup_branch( topic )
10
+ "backup/#{user}/#{topic}"
11
+ end
12
+
13
+ def wip_branch( topic )
14
+ "wip/#{user}/#{topic}"
15
+ end
16
+
17
+ def rejected_branch( topic )
18
+ "rejected/#{user}/#{topic}"
19
+ end
20
+
21
+ def review_branch( topic, user=user )
22
+ "review/#{user}/#{topic}"
23
+ end
24
+
25
+ def remote_rejected_branch( topic, user=user )
26
+ "rejected/#{user}/#{topic}"
27
+ end
28
+
29
+
30
+ def find_remote_review_branch( topic )
31
+ others_review_branches.find{|b| b.index topic}
32
+ end
33
+
34
+
35
+ def user_topic_name( branch )
36
+ if branch =~ %r{^origin}
37
+ branch =~ %r{^\S*?/\S*?/(\S*?)/(\S*)}
38
+ [$1, $2]
39
+ else
40
+ branch =~ %r{^\S*?/(\S*?)/(\S*)}
41
+ [$1, $2]
42
+ end
43
+ end
44
+
45
+ def topic_parts( spec )
46
+ p = {}
47
+ parts = spec.split( '/' )
48
+ case parts.size
49
+ when 2
50
+ p[:user], p[:topic] = parts
51
+ when 1
52
+ p[:topic] = parts.first
53
+ else
54
+ raise "Unexpected topic: #{spec}"
55
+ end
56
+ p
57
+ end
58
+
59
+
60
+ def user
61
+ @@user ||= (ENV['USER'] || `whoami`)
62
+ end
63
+
64
+ def current_topic
65
+ current_branch =~ %r{wip/\S*?/(\S*)}
66
+ $1
67
+ end
68
+
69
+ def current_branch
70
+ @@current_branch ||= capture_git( "branch --no-color" ).split( "\n" ).find do |b|
71
+ b =~ %r{^\*}
72
+ end[ 2..-1 ]
73
+ end
74
+
75
+ def branches
76
+ @@branches ||= capture_git( "branch --no-color" ).split( "\n" ).map{|b| b[2..-1]}
77
+ end
78
+
79
+ def remote_branches
80
+ @@remote_branches ||= capture_git( "branch -r --no-color" ).split( "\n" ).map{|b| b[2..-1]}
81
+ end
82
+
83
+ def others_review_branches
84
+ remote_branches.select do
85
+ |b| b =~ %r{/review/}
86
+ end.reject do |b|
87
+ b =~ %r{/#{user}/}
88
+ end
89
+ end
90
+
91
+ def remote_branches_organized
92
+ @@remote_branches_organized ||= (
93
+ rb = remote_branches.dup
94
+ # Convert a bunch of remote branch names, like
95
+ # origin/HEAD -> origin/masterr
96
+ # origin/master
97
+ # origin/review/user1/topic1
98
+ # origin/something-else
99
+ # origin/rejected/user2/topic2
100
+ #
101
+ # Into a hash with keys 'review' and 'rejected' pointing to hashes of
102
+ # user-topic(s) pairs.
103
+ rb.map!{|s| s.gsub( /->.*/, '')}
104
+ rb.map!{|s| s.strip.split( '/' )}
105
+ namespace_ut = rb.group_by{|remote, namespace, user, topic| namespace if topic}
106
+ namespace_ut.reject!{|k,v| not %w(rejected review).include? k}
107
+
108
+ namespace_ut.each do |k,v|
109
+ v.each{|a| a.shift( 2 )}
110
+ v = namespace_ut[k] = v.group_by{|user, topic| user if topic}
111
+ v.each{|kk,vv| vv.each(&:shift); vv.flatten!}
112
+ end
113
+
114
+ namespace_ut.symbolize_keys!
115
+ namespace_ut[:review] ||= {}
116
+ namespace_ut[:rejected] ||= {}
117
+
118
+ namespace_ut[:review].reject!{|k,v| k == user}
119
+ namespace_ut
120
+ )
121
+ end
122
+
123
+ def oldest_review_branch
124
+ return nil if others_review_branches.empty?
125
+
126
+ commits_by_age = capture_git([
127
+ "log --date-order --reverse --pretty=format:%d",
128
+ "^origin/master #{others_review_branches.join( ' ' )}",
129
+ ].join( " " )).split( "\n" )
130
+
131
+ commits_by_age.find do |ref|
132
+ # no ‘,’, i.e. only one ref matches the commit
133
+ ref.index( ',' ).nil?
134
+ end.strip[ 1..-2 ] # chomp the leading and trailing parenthesis
135
+ end
136
+
137
+ def oldest_review_user_topic
138
+ user_topic_name( oldest_review_branch )
139
+ end
140
+
141
+ def on_review_branch?
142
+ current_branch =~ %r{^review/}
143
+ end
144
+
145
+ end
146
+
147
+ def self.included( base )
148
+ base.extend ClassMethods
149
+ end
150
+ end
@@ -4,12 +4,18 @@
4
4
  require 'active_support'
5
5
  require 'active_support/core_ext/hash/keys'
6
6
 
7
- require 'util'
7
+ require 'core_ext'
8
+ require 'git_topic/git'
9
+ require 'git_topic/naming'
8
10
 
9
11
 
10
12
  module GitTopic
13
+ include GitTopic::Git
14
+ include GitTopic::Naming
15
+
11
16
  GlobalOptKeys = [ :verbose, :help, :verbose_given ]
12
17
 
18
+
13
19
  class << self
14
20
 
15
21
  # Switch to a branch for the given topic.
@@ -116,17 +122,21 @@ module GitTopic
116
122
  if review_branches.empty?
117
123
  puts "nothing to review."
118
124
  return
125
+ else
126
+ user, topic = oldest_review_user_topic
119
127
  end
120
-
121
- user, topic = oldest_review_user_topic
122
128
  else
123
- user, topic = spec.split( '/' )
129
+ p = topic_parts( spec )
130
+ user, topic = p[:user], p[:topic]
124
131
  end
125
132
 
126
133
  if remote_topic_branch = find_remote_review_branch( topic )
134
+ # Get the actual user/topic, e.g. to get the user if spec only specifies
135
+ # the topic.
136
+ real_user, real_topic = user_topic_name( remote_topic_branch )
127
137
  git [
128
138
  switch_to_branch(
129
- review_branch( topic, user ),
139
+ review_branch( real_topic, real_user ),
130
140
  remote_topic_branch )]
131
141
  else
132
142
  raise "No review topic found matching ‘#{spec}’"
@@ -200,176 +210,6 @@ module GitTopic
200
210
  ]
201
211
  end
202
212
 
203
-
204
- private
205
-
206
-
207
- def backup_branch( topic )
208
- "backup/#{user}/#{topic}"
209
- end
210
-
211
- def wip_branch( topic )
212
- "wip/#{user}/#{topic}"
213
- end
214
-
215
- def rejected_branch( topic )
216
- "rejected/#{user}/#{topic}"
217
- end
218
-
219
- def review_branch( topic, user=user )
220
- "review/#{user}/#{topic}"
221
- end
222
-
223
- def remote_rejected_branch( topic, user=user )
224
- "rejected/#{user}/#{topic}"
225
- end
226
-
227
-
228
- def find_remote_review_branch( topic )
229
- others_review_branches.find{|b| b.index topic}
230
- end
231
-
232
-
233
- def user_topic_name( branch )
234
- if branch =~ %r{^origin}
235
- branch =~ %r{^\S*?/\S*?/(\S*?)/(\S*)}
236
- [$1, $2]
237
- else
238
- branch =~ %r{^\S*?/(\S*?)/(\S*)}
239
- [$1, $2]
240
- end
241
- end
242
-
243
-
244
- def user
245
- @@user ||= (ENV['USER'] || `whoami`)
246
- end
247
-
248
- def current_topic
249
- current_branch =~ %r{wip/\S*?/(\S*)}
250
- $1
251
- end
252
-
253
- def current_branch
254
- @@current_branch ||= capture_git( "branch --no-color" ).split( "\n" ).find do |b|
255
- b =~ %r{^\*}
256
- end[ 2..-1 ]
257
- end
258
-
259
- def branches
260
- @@branches ||= capture_git( "branch --no-color" ).split( "\n" ).map{|b| b[2..-1]}
261
- end
262
-
263
- def remote_branches
264
- @@remote_branches ||= capture_git( "branch -r --no-color" ).split( "\n" ).map{|b| b[2..-1]}
265
- end
266
-
267
- def others_review_branches
268
- remote_branches.select do
269
- |b| b =~ %r{/review/}
270
- end.reject do |b|
271
- b =~ %r{/#{user}/}
272
- end
273
- end
274
-
275
- def remote_branches_organized
276
- @@remote_branches_organized ||= (
277
- rb = remote_branches.dup
278
- # Convert a bunch of remote branch names, like
279
- # origin/HEAD -> origin/masterr
280
- # origin/master
281
- # origin/review/user1/topic1
282
- # origin/something-else
283
- # origin/rejected/user2/topic2
284
- #
285
- # Into a hash with keys 'review' and 'rejected' pointing to hashes of
286
- # user-topic(s) pairs.
287
- rb.map!{|s| s.gsub( /->.*/, '')}
288
- rb.map!{|s| s.strip.split( '/' )}
289
- namespace_ut = rb.group_by{|remote, namespace, user, topic| namespace if topic}
290
- namespace_ut.reject!{|k,v| not %w(rejected review).include? k}
291
-
292
- namespace_ut.each do |k,v|
293
- v.each{|a| a.shift( 2 )}
294
- v = namespace_ut[k] = v.group_by{|user, topic| user if topic}
295
- v.each{|kk,vv| vv.each(&:shift); vv.flatten!}
296
- end
297
-
298
- namespace_ut.symbolize_keys!
299
- namespace_ut[:review] ||= {}
300
- namespace_ut[:rejected] ||= {}
301
-
302
- namespace_ut[:review].reject!{|k,v| k == user}
303
- namespace_ut
304
- )
305
- end
306
-
307
- def oldest_review_branch
308
- return nil if others_review_branches.empty?
309
-
310
- commits_by_age = capture_git([
311
- "log --date-order --reverse --pretty=format:%d",
312
- "^origin/master #{others_review_branches.join( ' ' )}",
313
- ].join( " " )).split( "\n" )
314
-
315
- commits_by_age.find do |ref|
316
- # no ‘,’, i.e. only one ref matches the commit
317
- ref.index( ',' ).nil?
318
- end.strip[ 1..-2 ] # chomp the leading and trailing parenthesis
319
- end
320
-
321
- def oldest_review_user_topic
322
- user_topic_name( oldest_review_branch )
323
- end
324
-
325
- def on_review_branch?
326
- current_branch =~ %r{^review/}
327
- end
328
-
329
- def working_tree_clean?
330
- git [ "diff --quiet", "diff --quiet --cached" ]
331
- $?.success?
332
- end
333
-
334
- def working_tree_dirty?
335
- not working_tree_clean?
336
- end
337
-
338
-
339
- def display_git_output?
340
- @@display_git_output ||= false
341
- end
342
-
343
- def display_git_output!
344
- @@display_git_output = true
345
- end
346
-
347
-
348
- def switch_to_branch( branch, tracking=nil )
349
- if branches.include?( branch )
350
- "checkout #{branch}"
351
- else
352
- "checkout -b #{branch} #{tracking}"
353
- end
354
- end
355
-
356
- def cmd_redirect_suffix( opts )
357
- if !opts[:show] && !display_git_output?
358
- "> /dev/null 2> /dev/null"
359
- end
360
- end
361
-
362
- def git( cmds=[], opts={} )
363
- cmds = [cmds] if cmds.is_a? String
364
- redir = cmd_redirect_suffix( opts )
365
- system cmds.map{|c| "git #{c} #{redir}"}.join( " && " )
366
- end
367
-
368
- def capture_git( cmds=[] )
369
- cmds = [cmds] if cmds.is_a? String
370
- redir = "2> /dev/null" unless display_git_output?
371
- `#{cmds.map{|c| "git #{c} #{redir}"}.join( " && " )}`
372
- end
373
213
  end
374
214
  end
375
215
 
@@ -258,6 +258,17 @@ describe GitTopic do
258
258
  git_branch_merge.should == 'refs/heads/review/user24601/ninja-basic'
259
259
  end
260
260
 
261
+ it "
262
+ should accept only a topic arg (vice <user>/<topic>) when the topic is
263
+ unambiguous.
264
+ ".oneline do
265
+ git_remote_branches.should include 'review/user24601/ninja-basic'
266
+ GitTopic.review( 'ninja-basic' )
267
+ git_branch.should == 'review/user24601/ninja-basic'
268
+ git_branch_remote.should == 'origin'
269
+ git_branch_merge.should == 'refs/heads/review/user24601/ninja-basic'
270
+ end
271
+
261
272
  it "should error if an illegal topic is specified" do
262
273
  lambda{ GitTopic.review( 'fakeuser/faketopic' )}.should raise_error
263
274
  end
data/spec/spec_helper.rb CHANGED
@@ -1,31 +1,29 @@
1
1
  # encoding: utf-8
2
- require 'git-topic'
2
+ require 'git_topic'
3
3
 
4
4
 
5
5
  # Disable caching on GitTopic for specs since we're calling the methods directly
6
6
  # rather than assuming atmoic invocations.
7
- module GitTopic
8
- class << self
9
- %w( current_branch remote_branches remote_branches_organized branches
10
- ).each do |m|
11
-
12
- define_method( "#{m}_with_nocache" ) do
13
- rv = send( "#{m}_without_nocache" )
14
- self.class_variable_set( "@@#{m}", nil )
15
- rv
16
- end
17
- alias_method_chain m.to_sym, :nocache
7
+ class << GitTopic
8
+ %w( current_branch remote_branches remote_branches_organized branches
9
+ ).each do |m|
10
+
11
+ define_method( "#{m}_with_nocache" ) do
12
+ rv = send( "#{m}_without_nocache" )
13
+ GitTopic::Naming::ClassMethods.class_variable_set( "@@#{m}", nil )
14
+ rv
18
15
  end
16
+ alias_method_chain m.to_sym, :nocache
17
+ end
19
18
 
20
- def git_with_implicit_capture( cmds=[], opts={} )
21
- if opts[:show]
22
- puts capture_git( cmds )
23
- else
24
- git_without_implicit_capture( cmds, opts )
25
- end
19
+ def git_with_implicit_capture( cmds=[], opts={} )
20
+ if opts[:show]
21
+ puts capture_git( cmds )
22
+ else
23
+ git_without_implicit_capture( cmds, opts )
26
24
  end
27
- alias_method_chain :git, :implicit_capture
28
25
  end
26
+ alias_method_chain :git, :implicit_capture
29
27
  end
30
28
 
31
29
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 3
9
- version: 0.1.3
8
+ - 4
9
+ version: 0.1.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - David J. Hamilton
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-07-08 00:00:00 -07:00
17
+ date: 2010-07-13 00:00:00 -07:00
18
18
  default_executable: git-topic
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -84,9 +84,11 @@ files:
84
84
  - autotest/discover.rb
85
85
  - bin/git-topic
86
86
  - git-topic.gemspec
87
- - lib/git-topic.rb
88
- - lib/util.rb
89
- - spec/git-topic_spec.rb
87
+ - lib/core_ext.rb
88
+ - lib/git_topic.rb
89
+ - lib/git_topic/git.rb
90
+ - lib/git_topic/naming.rb
91
+ - spec/git_topic_spec.rb
90
92
  - spec/spec_helper.rb
91
93
  - spec/template/origin/HEAD
92
94
  - spec/template/origin/config
@@ -155,4 +157,4 @@ specification_version: 3
155
157
  summary: git command around reviewed topic branches
156
158
  test_files:
157
159
  - spec/spec_helper.rb
158
- - spec/git-topic_spec.rb
160
+ - spec/git_topic_spec.rb
File without changes