git-whistles 0.5.1 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,7 +3,6 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
- Gemfile.lock
7
6
  pkg
8
7
  rdoc
9
8
  tmp
data/Gemfile.lock ADDED
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ git-whistles (0.6.1)
5
+ pivotal-tracker (~> 0.5.6)
6
+ term-ansicolor
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ builder (3.1.3)
12
+ coderay (1.0.7)
13
+ happymapper (0.4.0)
14
+ libxml-ruby (~> 2.0)
15
+ libxml-ruby (2.3.3)
16
+ method_source (0.8)
17
+ mime-types (1.19)
18
+ nokogiri (1.5.5)
19
+ pivotal-tracker (0.5.6)
20
+ builder
21
+ builder
22
+ happymapper (>= 0.3.2)
23
+ happymapper (>= 0.3.2)
24
+ nokogiri (>= 1.4.3)
25
+ nokogiri (~> 1.4)
26
+ rest-client (~> 1.6.0)
27
+ rest-client (~> 1.6.0)
28
+ pry (0.9.10)
29
+ coderay (~> 1.0.5)
30
+ method_source (~> 0.8)
31
+ slop (~> 3.3.1)
32
+ pry-nav (0.2.2)
33
+ pry (~> 0.9.10)
34
+ rake (0.9.2.2)
35
+ rest-client (1.6.7)
36
+ mime-types (>= 1.16)
37
+ slop (3.3.2)
38
+ term-ansicolor (1.0.7)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ bundler (>= 1.0.0)
45
+ git-whistles!
46
+ pry
47
+ pry-nav
48
+ rake
data/README.md CHANGED
@@ -12,11 +12,12 @@ Use it with:
12
12
 
13
13
  - `git ff-all-branches [-f] [-p] [-v]`. Fast-forward all local tracking branches to their remote counterpart (where possible). Very useful on big projects.
14
14
  - `git stash-and-checkout [branch]` As the name implies: stash and checkout another branch.
15
- - `git-pull-request [your-branch] [target-branch]` Open your browser at a Github pull-request page for the specified branch (defaults to the current `head`). If you're using Pivotal Tracker and your branch has a story number in its name, populates your pull request with story details.
15
+ - `git-pull-request [--from your-branch] [--to target-branch]` Open your browser at a Github pull-request page for the specified branch (defaults to the current `head`). If you're using Pivotal Tracker and your branch has a story number in its name, populates your pull request with story details.
16
16
  - `git outstanding-features [from-branch] [to-branch]` List the pull requests merged in `[to-branch]` but not in `[from-branch]`. Useful to prepare a list of stuff you're oging to deploy. Defaults to listing what's on `origin/master` but not on `origin/production`.
17
17
  - `git chop [branch]` Delete the local and origin copy of a branch. Useful to close feature branches once a feature is completed.
18
18
  - `git list-branches [-l] [-r] [-i integration-branch]` Colourful listing of all local or origin branches, and their distance to an integration branch (`master` by default).
19
19
  - `git merge-po <ancestor> <left> <right>` Merge engine for GetText PO files.
20
+ - `git select <story-id>` Checkout a local branch with the matching number. If not found, lists remote branches
20
21
 
21
22
  ### More details on some of the commands
22
23
 
@@ -6,53 +6,25 @@
6
6
  #
7
7
  require 'ostruct'
8
8
  require 'optparse'
9
- require 'logger'
10
9
  require 'term/ansicolor'
10
+ require 'git-whistles/logger'
11
+ require 'git-whistles/app'
11
12
 
12
13
  ############################################################################
13
14
 
14
15
 
15
- class App
16
-
17
- DEFAULTS = {
18
- :fetch => false,
19
- :dry_run => false,
20
- :remote => 'origin',
21
- :loglevel => Logger::WARN
22
- }
23
-
24
- class Logger < ::Logger
25
- Colors = {
26
- 'DEBUG' => :reset,
27
- 'INFO' => :green,
28
- 'WARN' => :yellow,
29
- 'ERROR' => :red,
30
- 'FATAL' => :red,
31
- 'UNKNOWN' => :red
32
- }
33
-
34
- def initialize(*args)
35
- super
36
- self.formatter = self.method(:custom_formatter)
37
- end
38
-
39
- def custom_formatter(severity, time, progname, msg)
40
- Term::ANSIColor.send(Colors[severity], "#{msg}\n")
41
- end
42
- end
43
-
16
+ class App < Git::Whistles::App
44
17
 
45
18
  def initialize
46
- @options = OpenStruct.new(DEFAULTS)
19
+ super
47
20
  @local_branches = {}
48
21
  @remote_branches = {}
49
22
  @current_branch = nil
50
- @log = Logger.new($stderr)
51
23
  end
52
24
 
53
25
 
54
26
  def main(args)
55
- parse_args!(args)
27
+ super
56
28
  log.level = options.loglevel
57
29
 
58
30
  if options.fetch
@@ -69,11 +41,19 @@ class App
69
41
 
70
42
  private
71
43
 
72
- attr :options
44
+ def defaults
45
+ {
46
+ :fetch => false,
47
+ :dry_run => false,
48
+ :remote => 'origin',
49
+ :loglevel => Logger::WARN
50
+ }
51
+ end
52
+
53
+
73
54
  attr :local_branches
74
55
  attr :remote_branches
75
56
  attr :current_branch
76
- attr :log
77
57
 
78
58
 
79
59
  def process_branch(branch_name)
@@ -90,20 +70,20 @@ class App
90
70
  end
91
71
 
92
72
  if branch_name == current_branch
93
- if run('git status --porcelain').strip.empty?
73
+ if run!('git status --porcelain').strip.empty?
94
74
  flag = (options.loglevel > Logger::INFO) ? '-q' : ''
95
- run("git merge --ff-only #{flag} #{new_head}") unless options.dry_run
75
+ run!("git merge --ff-only #{flag} #{new_head}") unless options.dry_run
96
76
  else
97
77
  log.warn('not merging current branch as it has local changes')
98
78
  return
99
79
  end
100
80
  else
101
- merge_base = run("git merge-base #{old_head} #{new_head}").strip
81
+ merge_base = run!("git merge-base #{old_head} #{new_head}").strip
102
82
  if merge_base != old_head
103
83
  log.warn("cannot fast-forward #{branch_name}")
104
84
  return
105
85
  end
106
- run("git update-ref refs/heads/#{branch_name} #{new_head} #{old_head}")
86
+ run!("git update-ref refs/heads/#{branch_name} #{new_head} #{old_head}")
107
87
  end
108
88
 
109
89
  log.info("#{branch_name}: #{short_sha old_head} -> #{short_sha new_head}")
@@ -138,39 +118,18 @@ class App
138
118
 
139
119
 
140
120
  def parse_args!(args)
141
- begin
142
- option_parser.parse!(args)
143
- rescue OptionParser::InvalidOption => error
144
- die error.message, :usage => true
145
- end
121
+ super
146
122
 
147
- if ARGV.any?
123
+ if args.any?
148
124
  die "this command does not take any argument besides flags", :usage => true
149
125
  end
150
126
  end
151
127
 
152
128
 
153
- def run(command)
154
- result = %x(#{command})
155
- return result if $? == 0
156
- die "command '#{command}' failed"
157
- end
158
-
159
-
160
- def die(message, options = {})
161
- puts Term::ANSIColor.red(message)
162
- if options[:usage]
163
- puts
164
- puts option_parser.help
165
- end
166
- exit 1
167
- end
168
-
169
-
170
129
  def load_refs
171
- @current_branch = run("git symbolic-ref HEAD").strip.gsub(%r(^refs/heads/), '')
130
+ @current_branch = run!("git symbolic-ref HEAD").strip.gsub(%r(^refs/heads/), '')
172
131
 
173
- run('git show-ref').strip.split(/\n+/).each do |line|
132
+ run!('git show-ref').strip.split(/\n+/).each do |line|
174
133
  line =~ %r(([a-f0-9]{40}) refs/(remotes/#{options.remote}|heads)/(.*)) or next
175
134
  if $2 == 'heads'
176
135
  @local_branches[$3] = $1
@@ -187,4 +146,4 @@ end
187
146
 
188
147
  ############################################################################
189
148
 
190
- App.new.main(ARGV)
149
+ App.run!
data/bin/git-pull-request CHANGED
@@ -7,114 +7,160 @@
7
7
  # Assumes the branches are named
8
8
  # <team>/<branch-title>-<story-id>
9
9
  #
10
- # Copyright (C) 2012 Julien Letessier
11
- #
12
- # Permission is hereby granted, free of charge, to any person obtaining a copy of
13
- # this software and associated documentation files (the "Software"), to deal in
14
- # the Software without restriction, including without limitation the rights to
15
- # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
16
- # of the Software, and to permit persons to whom the Software is furnished to do
17
- # so, subject to the following conditions:
18
- #
19
- # The above copyright notice and this permission notice shall be included in all
20
- # copies or substantial portions of the Software.
21
- #
22
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
- # SOFTWARE.
29
- #
30
- # require 'CGI'
31
10
  require 'rubygems'
32
11
  require 'pivotal-tracker'
12
+ require 'optparse'
13
+ require 'cgi'
33
14
  require 'term/ansicolor'
15
+ require 'git-whistles/app'
34
16
 
35
- origin_url = `git config --get remote.origin.url`.strip
36
- unless origin_url =~ /github\.com/
37
- puts "origin does not have a Github URL !"
38
- exit 1
39
- end
40
17
 
41
- repo = origin_url.sub(/.*github\.com[\/:]/,'').sub(/\.git$/,'')
18
+ class App < Git::Whistles::App
42
19
 
43
- if ARGV[0]
44
- branch = ARGV[0]
45
- else
46
- branch = `git symbolic-ref HEAD`.gsub(%r(^refs/heads/), "")
47
- exit $? unless $? == 0
48
- end
20
+ Browsers = %w(xdg-open open firefox iceweasel)
49
21
 
50
- if branch == 'master'
51
- puts "You cannot issue a pull request for master !"
52
- exit 1
53
- end
22
+ def initialize
23
+ super
24
+ end
54
25
 
55
- against = ARGV[1] || 'master'
56
26
 
57
- # build the base query
58
- query = {
59
- :base_repo => repo,
60
- :base_ref => against,
61
- :head_ref => branch
62
- }
27
+ def main(args)
28
+ super
29
+ parse_args!(args)
63
30
 
64
- # guess team name
65
- if branch =~ %r{^(\w+)/.*}
66
- team = $1.capitalize
67
- end
31
+ if args.count > 0
32
+ die "Too many arguments", :usage => true
33
+ end
68
34
 
69
- # guess title.
70
- title = branch.split('/').last.split(/[_-]/).delete_if { |word| word =~ /^\d+$/ }.join(' ').capitalize
71
- query[:title] = "#{team}: #{title}"
72
-
73
- # find the PT story, or fall back to the branch-name-based titling
74
- if branch =~ /(\d+)$/
75
- story_id = $1.to_i
76
- token = `git config pivotal-tracker.token`.strip
77
- if token.empty?
78
- puts Term::ANSIColor.yellow %Q{
79
- I don't know your Pivotal Tracker token!
80
- Please set it with:
81
- $ git config pivotal-tracker.token <token>
35
+ if options.from == options.to
36
+ die "You cannot issue a pull request to the same branch (#{options.from})."
37
+ end
38
+
39
+ # build the base query
40
+ query = {
41
+ :base_repo => repo,
42
+ :base_ref => options.to,
43
+ :head_ref => options.from
82
44
  }
83
- exit 1
84
- else
85
- $stdout.write Term::ANSIColor.green "Finding your project and story "
86
- $stdout.flush
45
+
46
+ # guess team name
47
+ if options.from =~ %r{^(\w+)/.*}
48
+ team = $1.capitalize
49
+ else
50
+ team = nil
51
+ end
52
+
53
+ # guess title.
54
+ title = options.from.split('/').last.split(/[_-]/).delete_if { |word| word =~ /^\d+$/ }.join(' ').capitalize
55
+ query[:title] = team ? "#{team}: #{title}" : title
56
+
57
+ # add Pivotal infos
58
+ add_pivotal_info(query, $1.to_i) if options.from =~ /(\d+)$/
59
+
60
+ query_string = query.map { |key,value|
61
+ "#{CGI.escape key.to_s}=#{CGI.escape value}"
62
+ }.join('&')
63
+ url = "https://github.com/#{repo}/pull/new?#{query_string}"
64
+ puts "Preparing a pull request for branch #{options.from}"
65
+
66
+ unless launch_browser(url)
67
+ log.warn "Sorry, I don't know how to launch a web browser on your system. You can open it yourself and paste this URL:\n#{url}"
68
+ end
69
+ end
70
+
71
+
72
+ private
73
+
74
+
75
+ def defaults
76
+ {
77
+ :from => run!('git symbolic-ref HEAD').strip.gsub(%r(^refs/heads/), ""),
78
+ :to => 'master',
79
+ :remote => 'origin'
80
+ }
81
+ end
82
+
83
+ def option_parser
84
+ @option_parser ||= OptionParser.new do |op|
85
+ op.banner = "Usage: git pull-request [options]"
86
+
87
+ op.on("-f", "--from YOUR_BRANCH", "Branch to issue pull request for [head]") do |v|
88
+ options.from = v
89
+ end
90
+
91
+ op.on("-to", "--to UPSTREAM_BRANCH", "Branch into which you want your code merged [master]") do |v|
92
+ options.to = v
93
+ end
94
+
95
+ op.on("-r", "--remote NAME", "The remote you're sending this to [origin]") do |v|
96
+ options.to = v
97
+ end
98
+ end
99
+ end
100
+
101
+
102
+ def origin_url
103
+ @origin_url ||= begin
104
+ run!("git config --get remote.#{options.remote}.url").strip.tap do |url|
105
+ url =~ /github\.com/ or die "origin does not have a Github URL !"
106
+ end
107
+ end
108
+ end
109
+
110
+
111
+ def repo
112
+ @repo ||= origin_url.sub(/.*github\.com[\/:]/,'').sub(/\.git$/,'')
113
+ end
114
+
115
+
116
+ def add_pivotal_info(query, story_id)
117
+ token = `git config pivotal-tracker.token`.strip
118
+ if token.empty?
119
+ puts Term::ANSIColor.yellow %Q{
120
+ Your branch appears to have a story ID,
121
+ but I don't know your Pivotal Tracker token!
122
+ Please set it with:
123
+ $ git config [--global] pivotal-tracker.token <token>
124
+ }
125
+ die "Aborting."
126
+ end
127
+
128
+ log.info "Finding your project and story¬"
87
129
 
88
130
  PivotalTracker::Client.token = token
89
131
  story, project = PivotalTracker::Project.all.find do |project|
90
- $stdout.write Term::ANSIColor.green '.'
91
- $stdout.flush
132
+ log.info ''
92
133
  story = project.stories.find(story_id) and break story, project
93
134
  end
94
- $stdout.puts
135
+ log.info '.'
95
136
 
96
137
  if story.nil?
97
- puts Term::ANSIColor.yellow "Apologies... I could not find story #{story_id}."
98
- else
99
- $stdout.puts Term::ANSIColor.green "Found story #{story_id} in '#{project.name}'"
138
+ log.warn "Apologies... I could not find story #{story_id}."
139
+ return
140
+ end
141
+
142
+ log.info "Found story #{story_id} in '#{project.name}'"
100
143
 
101
- headline = "Pivotal tracker story [##{story_id}](#{story.url}) in project *#{project.name}*:"
102
- description = story.description.split("\n").map { |line| "> #{line}" }.join("\n")
103
- body = "#{headline}\n\n#{description}"
104
- title = "#{project.name}: #{story.name} [##{story.id}]"
144
+ headline = "Pivotal tracker story [##{story_id}](#{story.url}) in project *#{project.name}*:"
145
+ description = story.description.split("\n").map { |line| "> #{line}" }.join("\n")
146
+ body = "#{headline}\n\n#{description}"
147
+ title = "#{project.name}: #{story.name} [##{story.id}]"
148
+ query.merge! :subject => story.name, :body => body, :title => title
149
+ return
150
+ end
105
151
 
106
- query.merge! :subject => story.name, :body => body, :title => title
152
+ def launch_browser(url)
153
+ Browsers.each do |command|
154
+ next if run("which #{command}").strip.empty?
155
+ system command, url
156
+ return true
107
157
  end
158
+ return false
108
159
  end
109
- end
110
160
 
111
- query_string = query.map { |key,value| "#{CGI.escape key.to_s}=#{CGI.escape value}"}.join('&')
112
- url = "https://github.com/#{repo}/pull/new?#{query_string}"
113
- puts "Preparing a pull request for branch #{branch}"
114
161
 
115
- # Use +xdg-open+ on Linux, +open+ on Darwin
116
- unless `which xdg-open`.strip.empty?
117
- system "xdg-open", url
118
- else
119
- system "open", url
120
162
  end
163
+
164
+ ############################################################################
165
+
166
+ App.run!
data/bin/git-select ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # git-select #story-id
4
+ #
5
+ # Looks up your current branches for the first occurence of
6
+ # the story-id and checkout it
7
+ #
8
+ require 'rubygems'
9
+ require 'term/ansicolor'
10
+
11
+ # Helper functions
12
+ def git_dir?
13
+ `git config --get remote.origin.url`.strip == ''
14
+ end
15
+
16
+ def process(branches)
17
+ branches.split("\n").map { |branch| branch.strip.gsub(%r(\* ), '')}
18
+ end
19
+
20
+ def select(branches, story_id)
21
+ branches.select { |branch| branch =~ /#{story_id}/ }
22
+ end
23
+
24
+
25
+ if git_dir?
26
+ puts "Not a valid git repo"
27
+ exit 1
28
+ end
29
+
30
+ if ARGV[0] && ARGV[0] =~ /^\d+$/
31
+ story_id = ARGV[0]
32
+ else
33
+ puts "story-id is not a number"
34
+ exit 1
35
+ end
36
+
37
+
38
+ # Find locally first
39
+ locals = process(`git branch`)
40
+
41
+ # Select matching locals
42
+ found = select(locals, story_id)
43
+
44
+ case found.size
45
+ when 0
46
+ puts Term::ANSIColor.yellow 'Failed lookup on local branches'
47
+ when 1
48
+ `git checkout #{found.first}`
49
+ exit 0
50
+ else
51
+ puts "Found #{found.size} matches on locals:"
52
+ found.each do |branch|
53
+ puts " #{branch}"
54
+ end
55
+ exit 1
56
+ end
57
+
58
+ # Find remote branch
59
+ remotes = process(`git branch -a`)
60
+
61
+ # Select matching remotes
62
+ found = select(remotes, story_id)
63
+
64
+ case found.size
65
+ when 0
66
+ puts Term::ANSIColor.yellow 'Failed lookup on remote branches'
67
+ else
68
+ puts "Found #{found.size} matches on remotes:"
69
+ found.each do |branch|
70
+ puts " #{branch.gsub(%r(^remotes/origin/), "")}"
71
+ end
72
+ exit 1
73
+ end
74
+
@@ -0,0 +1,75 @@
1
+ require 'ostruct'
2
+ require 'optparse'
3
+ require 'term/ansicolor'
4
+ require 'git-whistles/logger'
5
+
6
+
7
+ module Git::Whistles
8
+ class App
9
+
10
+ def initialize
11
+ @options = OpenStruct.new(defaults)
12
+ @log = Git::Whistles::Logger.new($stderr)
13
+ end
14
+
15
+
16
+ def main(args)
17
+ parse_args!(args)
18
+ end
19
+
20
+
21
+ def self.run!
22
+ new.main(ARGV)
23
+ end
24
+
25
+
26
+ protected
27
+
28
+ # default options hash
29
+ def defaults
30
+ {}
31
+ end
32
+
33
+ attr :options
34
+ attr :log
35
+
36
+
37
+ def option_parser
38
+ @option_parser ||= OptionParser.new do |op|
39
+ op.banner = "Usage: #{$0}"
40
+ end
41
+ end
42
+
43
+
44
+
45
+ def parse_args!(args)
46
+ begin
47
+ option_parser.parse!(args)
48
+ rescue OptionParser::InvalidOption => error
49
+ die error.message, :usage => true
50
+ end
51
+ end
52
+
53
+
54
+ def run(command)
55
+ %x(#{command})
56
+ end
57
+
58
+
59
+ def run!(command)
60
+ result = %x(#{command})
61
+ return result if $? == 0
62
+ die "command '#{command}' failed"
63
+ end
64
+
65
+
66
+ def die(message, options = {})
67
+ puts Term::ANSIColor.red(message)
68
+ if options[:usage]
69
+ puts
70
+ puts option_parser.help
71
+ end
72
+ exit 1
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,4 @@
1
+ # Git command helpers
2
+
3
+ module Git::Whistles::Helpers
4
+ end
@@ -0,0 +1,25 @@
1
+ require 'logger'
2
+ require 'git-whistles'
3
+
4
+ module Git::Whistles
5
+ class Logger < ::Logger
6
+ Colors = {
7
+ 'DEBUG' => :reset,
8
+ 'INFO' => :green,
9
+ 'WARN' => :yellow,
10
+ 'ERROR' => :red,
11
+ 'FATAL' => :red,
12
+ 'UNKNOWN' => :red
13
+ }
14
+
15
+ def initialize(*args)
16
+ super
17
+ self.formatter = self.method(:custom_formatter)
18
+ end
19
+
20
+ def custom_formatter(severity, time, progname, msg)
21
+ msg = msg.sub(/([^¬])$/,"\\1\n").sub(/¬$/,'')
22
+ Term::ANSIColor.send(Colors[severity], msg)
23
+ end
24
+ end
25
+ end
@@ -2,7 +2,7 @@ require 'pathname'
2
2
 
3
3
  module Git
4
4
  module Whistles
5
- VERSION = "0.5.1"
5
+ VERSION = "0.6.1"
6
6
  GEMDIR = Pathname.new(__FILE__).parent.parent.parent
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,128 +1,131 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: git-whistles
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 5
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 1
10
+ version: 0.6.1
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Julien Letessier
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-10-17 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
+
18
+ date: 2012-10-29 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ requirement: &id001 !ruby/object:Gem::Requirement
17
23
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 23
28
+ segments:
29
+ - 1
30
+ - 0
31
+ - 0
21
32
  version: 1.0.0
22
- type: :development
23
33
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
34
+ name: bundler
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ requirement: &id002 !ruby/object:Gem::Requirement
25
39
  none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: 1.0.0
30
- - !ruby/object:Gem::Dependency
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ prerelease: false
31
48
  name: rake
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: '0'
38
49
  type: :development
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ requirement: &id003 !ruby/object:Gem::Requirement
41
53
  none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
46
- - !ruby/object:Gem::Dependency
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ prerelease: false
47
62
  name: pry
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
63
  type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ requirement: &id004 !ruby/object:Gem::Requirement
57
67
  none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ prerelease: false
63
76
  name: pry-nav
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
77
  type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
- - !ruby/object:Gem::Dependency
79
- name: pivotal-tracker
80
- requirement: !ruby/object:Gem::Requirement
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
81
  none: false
82
- requirements:
82
+ requirements:
83
83
  - - ~>
84
- - !ruby/object:Gem::Version
84
+ - !ruby/object:Gem::Version
85
+ hash: 7
86
+ segments:
87
+ - 0
88
+ - 5
89
+ - 6
85
90
  version: 0.5.6
86
- type: :runtime
87
91
  prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
92
+ name: pivotal-tracker
93
+ type: :runtime
94
+ version_requirements: *id005
95
+ - !ruby/object:Gem::Dependency
96
+ requirement: &id006 !ruby/object:Gem::Requirement
89
97
  none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: 0.5.6
94
- - !ruby/object:Gem::Dependency
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ prerelease: false
95
106
  name: term-ansicolor
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ! '>='
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
107
  type: :runtime
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ! '>='
108
- - !ruby/object:Gem::Version
109
- version: '0'
108
+ version_requirements: *id006
110
109
  description: A few helpers for classic Git workflows
111
- email:
110
+ email:
112
111
  - julien.letessier@gmail.com
113
- executables:
112
+ executables:
114
113
  - git-chop
115
114
  - git-ff-all-branches
116
115
  - git-list-branches
117
116
  - git-merge-po
118
117
  - git-outstanding-features
119
118
  - git-pull-request
119
+ - git-select
120
120
  - git-stash-and-checkout
121
121
  extensions: []
122
+
122
123
  extra_rdoc_files: []
123
- files:
124
+
125
+ files:
124
126
  - .gitignore
125
127
  - Gemfile
128
+ - Gemfile.lock
126
129
  - LICENSE
127
130
  - README.md
128
131
  - Rakefile
@@ -132,9 +135,13 @@ files:
132
135
  - bin/git-merge-po
133
136
  - bin/git-outstanding-features
134
137
  - bin/git-pull-request
138
+ - bin/git-select
135
139
  - bin/git-stash-and-checkout
136
140
  - git-whistles.gemspec
137
141
  - lib/git-whistles.rb
142
+ - lib/git-whistles/app.rb
143
+ - lib/git-whistles/helpers.rb
144
+ - lib/git-whistles/logger.rb
138
145
  - lib/git-whistles/version.rb
139
146
  - libexec/git-chop.sh
140
147
  - libexec/git-list-branches.sh
@@ -142,32 +149,41 @@ files:
142
149
  - libexec/git-outstanding-features.sh
143
150
  - libexec/git-stash-and-checkout.sh
144
151
  - libexec/runner.rb
152
+ has_rdoc: true
145
153
  homepage: http://github.com/mezis/git-whistles
146
154
  licenses: []
155
+
147
156
  post_install_message:
148
157
  rdoc_options: []
149
- require_paths:
158
+
159
+ require_paths:
150
160
  - lib
151
- required_ruby_version: !ruby/object:Gem::Requirement
161
+ required_ruby_version: !ruby/object:Gem::Requirement
152
162
  none: false
153
- requirements:
154
- - - ! '>='
155
- - !ruby/object:Gem::Version
156
- version: '0'
157
- segments:
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ hash: 3
167
+ segments:
158
168
  - 0
159
- hash: 1223314009549717192
160
- required_rubygems_version: !ruby/object:Gem::Requirement
169
+ version: "0"
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
171
  none: false
162
- requirements:
163
- - - ! '>='
164
- - !ruby/object:Gem::Version
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ hash: 23
176
+ segments:
177
+ - 1
178
+ - 3
179
+ - 6
165
180
  version: 1.3.6
166
181
  requirements: []
182
+
167
183
  rubyforge_project:
168
- rubygems_version: 1.8.24
184
+ rubygems_version: 1.3.9.5
169
185
  signing_key:
170
186
  specification_version: 3
171
- summary: ! 'A few helpers for classic Git workflows: makes branching and merging,
172
- PO file handling, issuing pull requests slightly simpler.'
187
+ summary: "A few helpers for classic Git workflows: makes branching and merging, PO file handling, issuing pull requests slightly simpler."
173
188
  test_files: []
189
+