git-whistles 0.5.1 → 0.6.1

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/.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
+