git_reflow 0.2

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 ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ git_reflow (0.2)
5
+ github_api (= 0.6.5)
6
+ gli (= 2.0.0)
7
+ highline
8
+ httpclient
9
+ json_pure (= 1.7.5)
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ addressable (2.3.2)
15
+ aruba (0.4.11)
16
+ childprocess (>= 0.2.3)
17
+ cucumber (>= 1.1.1)
18
+ ffi (>= 1.0.11)
19
+ rspec (>= 2.7.0)
20
+ builder (3.0.0)
21
+ childprocess (0.3.5)
22
+ ffi (~> 1.0, >= 1.0.6)
23
+ crack (0.3.1)
24
+ cucumber (1.2.1)
25
+ builder (>= 2.1.2)
26
+ diff-lcs (>= 1.1.3)
27
+ gherkin (~> 2.11.0)
28
+ json (>= 1.4.6)
29
+ diff-lcs (1.1.3)
30
+ faraday (0.8.4)
31
+ multipart-post (~> 1.1)
32
+ ffi (1.1.5)
33
+ gherkin (2.11.2)
34
+ json (>= 1.4.6)
35
+ git (1.2.5)
36
+ github_api (0.6.5)
37
+ faraday (~> 0.8.1)
38
+ hashie (~> 1.2.0)
39
+ multi_json (~> 1.3)
40
+ nokogiri (~> 1.5.2)
41
+ oauth2
42
+ gli (2.0.0)
43
+ hashie (1.2.0)
44
+ highline (1.6.14)
45
+ httpauth (0.1)
46
+ httpclient (2.2.7)
47
+ jeweler (1.8.4)
48
+ bundler (~> 1.0)
49
+ git (>= 1.2.5)
50
+ rake
51
+ rdoc
52
+ json (1.7.5)
53
+ json_pure (1.7.5)
54
+ jwt (0.1.5)
55
+ multi_json (>= 1.0)
56
+ multi_json (1.3.6)
57
+ multipart-post (1.1.5)
58
+ nokogiri (1.5.5)
59
+ oauth2 (0.8.0)
60
+ faraday (~> 0.8)
61
+ httpauth (~> 0.1)
62
+ jwt (~> 0.1.4)
63
+ multi_json (~> 1.0)
64
+ rack (~> 1.2)
65
+ rack (1.4.1)
66
+ rake (0.9.2.2)
67
+ rdoc (3.12)
68
+ json (~> 1.4)
69
+ rspec (2.11.0)
70
+ rspec-core (~> 2.11.0)
71
+ rspec-expectations (~> 2.11.0)
72
+ rspec-mocks (~> 2.11.0)
73
+ rspec-core (2.11.1)
74
+ rspec-expectations (2.11.2)
75
+ diff-lcs (~> 1.1.3)
76
+ rspec-mocks (2.11.2)
77
+ webmock (1.8.9)
78
+ addressable (>= 2.2.7)
79
+ crack (>= 0.1.7)
80
+
81
+ PLATFORMS
82
+ ruby
83
+
84
+ DEPENDENCIES
85
+ aruba (~> 0.4.6)
86
+ git_reflow!
87
+ jeweler
88
+ rake
89
+ rdoc
90
+ rspec
91
+ webmock
data/README.rdoc ADDED
@@ -0,0 +1,39 @@
1
+ git-reflow
2
+ ==========
3
+ Tools to help build software that just works.
4
+
5
+ How it works
6
+ -------------
7
+ `$ git reflow setup`
8
+ Sets up your Github credentials
9
+
10
+ `$ git reflow start branch-name`
11
+ Creates new branch
12
+ Prompts for PT ticket numbers? (Keep the PT stuff as a plugin?)
13
+
14
+ `$ git reflow review [branch]`
15
+ Assumes remote 'origin'
16
+ Performs the following against [branch] or master if branch is not specified:
17
+ `git fetch origin`
18
+ - Are we up-to-date with changes from the destination?
19
+ - Fail with "origin/[branch] has newer changes" if no
20
+ - Run the test suite
21
+ - If fails, do not continue
22
+ - If not configured, fail with "Run test suite then use flag --green"
23
+ `git push origin current-branch` # Updates remote branch
24
+ - Do we have pull request?
25
+ - if no, create it and print "Pull request created at http://pull-url/"
26
+
27
+ `$ git reflow deliver [branch]`
28
+ - Do we have lgtm after last commit?
29
+ - If no, print "Still waiting for review" (Maybe provide a way to skip this with `--lgtm`?)
30
+ - Prompt "Accepted by:" and get name/email/github username of person who does acceptance
31
+ - Checkout destination branch
32
+ - Update destination from origin (`git pull origin [branch]`)
33
+ - Merge squashed (`git merge --squash branch-name`)
34
+ - Prepare commit message (Adds Closes #pull-request-number)
35
+ - Perform the commit
36
+ - Push to branch
37
+ - Delete the remote branch
38
+ - Delete the local branch
39
+ - Deploy (Maybe with flag `--deploy`)
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'rake'
2
+ require 'bundler/gem_tasks'
3
+ require 'cucumber'
4
+ require 'cucumber/rake/task'
5
+
6
+ Dir[File.join(File.dirname(__FILE__),'lib/tasks/*.rake')].each { |f| load f }
7
+
8
+ Cucumber::Rake::Task.new(:features) do |t|
9
+ t.cucumber_opts = "features --format pretty -x"
10
+ t.fork = false
11
+ end
12
+
13
+ task :default => [:spec, :cucumber]
data/bin/git-reflow ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env ruby
2
+ # 1.9 adds realpath to resolve symlinks; 1.8 doesn't
3
+ # have this method, so we add it so we get resolved symlinks
4
+ # and compatibility
5
+ unless File.respond_to? :realpath
6
+ class File #:nodoc:
7
+ def self.realpath path
8
+ return realpath(File.readlink(path)) if symlink?(path)
9
+ path
10
+ end
11
+ end
12
+ end
13
+ $: << File.expand_path(File.dirname(File.realpath(__FILE__)) + '/../lib')
14
+ require 'rubygems'
15
+ require 'gli'
16
+ require 'git_reflow'
17
+ require 'git_reflow/version'
18
+
19
+ include GLI::App
20
+
21
+ program_desc 'Git Reflow manages your git workflow.'
22
+
23
+ version GitReflow::VERSION
24
+
25
+ desc 'Describe some switch here'
26
+ switch [:s,:switch]
27
+
28
+ desc 'Describe some flag here'
29
+ default_value 'the default'
30
+ arg_name 'The name of the argument'
31
+ flag [:f,:flagname]
32
+
33
+ desc 'Setup your GitHub account'
34
+ command :setup do |c|
35
+ c.action do |global_options,options,args|
36
+ GitReflow.setup
37
+ end
38
+ end
39
+
40
+ desc 'Start will create a new feature branch and setup remote tracking'
41
+ arg_name 'Describe arguments to start here'
42
+ command :start do |c|
43
+ c.desc 'Describe a switch to start'
44
+ c.switch :s
45
+
46
+ c.desc 'Describe a flag to start'
47
+ c.default_value 'default'
48
+ c.flag :f
49
+ c.action do |global_options,options,args|
50
+
51
+ # Your command logic here
52
+ if args.empty?
53
+ raise "usage: git-reflow start [new-branch-name]"
54
+ else
55
+ `git push origin master:refs/heads/#{args[0]}`
56
+ `git fetch origin`
57
+ `git checkout --track -b #{args[0]} origin/#{args[0]}`
58
+ end
59
+ # If you have any errors, just raise them
60
+ # raise "that command made no sense"
61
+ end
62
+ end
63
+
64
+ desc 'Describe review here'
65
+ arg_name 'Describe arguments to review here'
66
+ command :review do |c|
67
+ c.action do |global_options,options,args|
68
+ review_options = {'base' => nil, 'title' => nil, 'body' => nil}
69
+ case args.length
70
+ when 3
71
+ review_options['base'] = args[0]
72
+ review_options['title'] = args[1]
73
+ review_options['body'] = args[2]
74
+ when 2
75
+ review_options['base'] = args[0]
76
+ review_options['title'] = args[1]
77
+ review_options['body'] = review_options['title']
78
+ when 1
79
+ review_options['base'] = args[0]
80
+ review_options['title'] = review_options['body'] = GitReflow.get_first_commit_message
81
+ else
82
+ review_options['title'] = review_options['body'] = GitReflow.get_first_commit_message
83
+ end
84
+ GitReflow.review review_options
85
+ end
86
+ end
87
+
88
+ desc 'deliver will merge your feature branch down to your base branch'
89
+ arg_name 'base_branch - the branch you want to merge into'
90
+ command :deliver do |c|
91
+ c.action do |global_options,options,args|
92
+ deliver_options = {'base' => nil, 'head' => nil}
93
+ case args.length
94
+ when 2
95
+ deliver_options['base'] = args[0]
96
+ deliver_options['head'] = args[1]
97
+ when 1
98
+ deliver_options['base'] = args[0]
99
+ end
100
+ GitReflow.deliver deliver_options
101
+ end
102
+ end
103
+
104
+ pre do |global,command,options,args|
105
+ # Pre logic here
106
+ # Return true to proceed; false to abourt and not call the
107
+ # chosen command
108
+ # Use skips_pre before a command to skip this block
109
+ # on that command only
110
+ true
111
+ end
112
+
113
+ post do |global,command,options,args|
114
+ # Post logic here
115
+ # Use skips_post before a command to skip this
116
+ # block on that command only
117
+ end
118
+
119
+ on_error do |exception|
120
+ # Error logic here
121
+ # return false to skip default error handling
122
+ true
123
+ end
124
+
125
+ exit run(ARGV)
@@ -0,0 +1,314 @@
1
+ #!/bin/sh
2
+ # git-flow -- A collection of Git extensions to provide high-level
3
+ # repository operations for Vincent Driessen's branching model.
4
+ #
5
+ # Original blog post presenting this model is found at:
6
+ # http://nvie.com/git-model
7
+ #
8
+ # Feel free to contribute to this project at:
9
+ # http://github.com/nvie/gitreflow
10
+ #
11
+ # Copyright 2010 Vincent Driessen. All rights reserved.
12
+ #
13
+ # Redistribution and use in source and binary forms, with or without
14
+ # modification, are permitted provided that the following conditions are met:
15
+ #
16
+ # 1. Redistributions of source code must retain the above copyright notice,
17
+ # this list of conditions and the following disclaimer.
18
+ #
19
+ # 2. Redistributions in binary form must reproduce the above copyright
20
+ # notice, this list of conditions and the following disclaimer in the
21
+ # documentation and/or other materials provided with the distribution.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR
24
+ # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
26
+ # EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
30
+ # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ #
34
+ # The views and conclusions contained in the software and documentation are
35
+ # those of the authors and should not be interpreted as representing official
36
+ # policies, either expressed or implied, of Vincent Driessen.
37
+ #
38
+
39
+ #
40
+ # Common functionality
41
+ #
42
+
43
+ # shell output
44
+ warn() { echo "$@" >&2; }
45
+ die() { warn "$@"; exit 1; }
46
+
47
+ escape() {
48
+ echo "$1" | sed 's/\([\.\+\$\*]\)/\\\1/g'
49
+ }
50
+
51
+ # set logic
52
+ has() {
53
+ local item=$1; shift
54
+ echo " $@ " | grep -q " $(escape $item) "
55
+ }
56
+
57
+ # basic math
58
+ min() { [ "$1" -le "$2" ] && echo "$1" || echo "$2"; }
59
+ max() { [ "$1" -ge "$2" ] && echo "$1" || echo "$2"; }
60
+
61
+ # basic string matching
62
+ startswith() { [ "$1" != "${1#$2}" ]; }
63
+ endswith() { [ "$1" != "${1%$2}" ]; }
64
+
65
+ #
66
+ # Git specific common functionality
67
+ #
68
+
69
+ git_local_branches() { git branch --no-color | sed 's/^[* ] //'; }
70
+ git_remote_branches() { git branch -r --no-color | sed 's/^[* ] //'; }
71
+ git_all_branches() { ( git branch --no-color; git branch -r --no-color) | sed 's/^[* ] //'; }
72
+ git_all_tags() { git tag; }
73
+
74
+ git_current_branch() {
75
+ git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g'
76
+ }
77
+
78
+ git_is_clean_working_tree() {
79
+ if ! git diff --no-ext-diff --ignore-submodules --quiet --exit-code; then
80
+ return 1
81
+ elif ! git diff-index --cached --quiet --ignore-submodules HEAD --; then
82
+ return 2
83
+ else
84
+ return 0
85
+ fi
86
+ }
87
+
88
+ git_repo_is_headless() {
89
+ ! git rev-parse --quiet --verify HEAD >/dev/null 2>&1
90
+ }
91
+
92
+ git_local_branch_exists() {
93
+ has $1 $(git_local_branches)
94
+ }
95
+
96
+ git_remote_branch_exists() {
97
+ has $1 $(git_remote_branches)
98
+ }
99
+
100
+ git_branch_exists() {
101
+ has $1 $(git_all_branches)
102
+ }
103
+
104
+ git_tag_exists() {
105
+ has $1 $(git_all_tags)
106
+ }
107
+
108
+ #
109
+ # git_compare_branches()
110
+ #
111
+ # Tests whether branches and their "origin" counterparts have diverged and need
112
+ # merging first. It returns error codes to provide more detail, like so:
113
+ #
114
+ # 0 Branch heads point to the same commit
115
+ # 1 First given branch needs fast-forwarding
116
+ # 2 Second given branch needs fast-forwarding
117
+ # 3 Branch needs a real merge
118
+ # 4 There is no merge base, i.e. the branches have no common ancestors
119
+ #
120
+ git_compare_branches() {
121
+ local commit1=$(git rev-parse "$1")
122
+ local commit2=$(git rev-parse "$2")
123
+ if [ "$commit1" != "$commit2" ]; then
124
+ local base=$(git merge-base "$commit1" "$commit2")
125
+ if [ $? -ne 0 ]; then
126
+ return 4
127
+ elif [ "$commit1" = "$base" ]; then
128
+ return 1
129
+ elif [ "$commit2" = "$base" ]; then
130
+ return 2
131
+ else
132
+ return 3
133
+ fi
134
+ else
135
+ return 0
136
+ fi
137
+ }
138
+
139
+ #
140
+ # git_is_branch_merged_into()
141
+ #
142
+ # Checks whether branch $1 is succesfully merged into $2
143
+ #
144
+ git_is_branch_merged_into() {
145
+ local subject=$1
146
+ local base=$2
147
+ local all_merges="$(git branch --no-color --contains $subject | sed 's/^[* ] //')"
148
+ has $base $all_merges
149
+ }
150
+
151
+ #
152
+ # gitreflow specific common functionality
153
+ #
154
+
155
+ # check if this repo has been inited for gitreflow
156
+ gitreflow_has_master_configured() {
157
+ local master=$(git config --get gitreflow.branch.master)
158
+ [ "$master" != "" ] && git_local_branch_exists "$master"
159
+ }
160
+
161
+ gitreflow_has_develop_configured() {
162
+ local develop=$(git config --get gitreflow.branch.develop)
163
+ [ "$develop" != "" ] && git_local_branch_exists "$develop"
164
+ }
165
+
166
+ gitreflow_has_prefixes_configured() {
167
+ git config --get gitreflow.prefix.feature >/dev/null 2>&1 && \
168
+ git config --get gitreflow.prefix.release >/dev/null 2>&1 && \
169
+ git config --get gitreflow.prefix.hotfix >/dev/null 2>&1 && \
170
+ git config --get gitreflow.prefix.support >/dev/null 2>&1 && \
171
+ git config --get gitreflow.prefix.versiontag >/dev/null 2>&1
172
+ }
173
+
174
+ gitreflow_is_initialized() {
175
+ gitreflow_has_master_configured && \
176
+ gitreflow_has_develop_configured && \
177
+ [ "$(git config --get gitreflow.branch.master)" != \
178
+ "$(git config --get gitreflow.branch.develop)" ] && \
179
+ gitreflow_has_prefixes_configured
180
+ }
181
+
182
+ # loading settings that can be overridden using git config
183
+ gitreflow_load_settings() {
184
+ export DOT_GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
185
+ export MASTER_BRANCH=$(git config --get gitreflow.branch.master)
186
+ export DEVELOP_BRANCH=$(git config --get gitreflow.branch.develop)
187
+ export ORIGIN=$(git config --get gitreflow.origin || echo origin)
188
+ }
189
+
190
+ #
191
+ # gitreflow_resolve_nameprefix
192
+ #
193
+ # Inputs:
194
+ # $1 = name prefix to resolve
195
+ # $2 = branch prefix to use
196
+ #
197
+ # Searches branch names from git_local_branches() to look for a unique
198
+ # branch name whose name starts with the given name prefix.
199
+ #
200
+ # There are multiple exit codes possible:
201
+ # 0: The unambiguous full name of the branch is written to stdout
202
+ # (success)
203
+ # 1: No match is found.
204
+ # 2: Multiple matches found. These matches are written to stderr
205
+ #
206
+ gitreflow_resolve_nameprefix() {
207
+ local name=$1
208
+ local prefix=$2
209
+ local matches
210
+ local num_matches
211
+
212
+ # first, check if there is a perfect match
213
+ if git_local_branch_exists "$prefix$name"; then
214
+ echo "$name"
215
+ return 0
216
+ fi
217
+
218
+ matches=$(echo "$(git_local_branches)" | grep "^$(escape "$prefix$name")")
219
+ num_matches=$(echo "$matches" | wc -l)
220
+ if [ -z "$matches" ]; then
221
+ # no prefix match, so take it literally
222
+ warn "No branch matches prefix '$name'"
223
+ return 1
224
+ else
225
+ if [ $num_matches -eq 1 ]; then
226
+ echo "${matches#$prefix}"
227
+ return 0
228
+ else
229
+ # multiple matches, cannot decide
230
+ warn "Multiple branches match prefix '$name':"
231
+ for match in $matches; do
232
+ warn "- $match"
233
+ done
234
+ return 2
235
+ fi
236
+ fi
237
+ }
238
+
239
+ #
240
+ # Assertions for use in git-flow subcommands
241
+ #
242
+
243
+ require_git_repo() {
244
+ if ! git rev-parse --git-dir >/dev/null 2>&1; then
245
+ die "fatal: Not a git repository"
246
+ fi
247
+ }
248
+
249
+ require_gitreflow_initialized() {
250
+ if ! gitreflow_is_initialized; then
251
+ die "fatal: Not a gitreflow-enabled repo yet. Please run \"git flow init\" first."
252
+ fi
253
+ }
254
+
255
+ require_clean_working_tree() {
256
+ git_is_clean_working_tree
257
+ local result=$?
258
+ if [ $result -eq 1 ]; then
259
+ die "fatal: Working tree contains unstaged changes. Aborting."
260
+ fi
261
+ if [ $result -eq 2 ]; then
262
+ die "fatal: Index contains uncommited changes. Aborting."
263
+ fi
264
+ }
265
+
266
+ require_local_branch() {
267
+ if ! git_local_branch_exists $1; then
268
+ die "fatal: Local branch '$1' does not exist and is required."
269
+ fi
270
+ }
271
+
272
+ require_remote_branch() {
273
+ if ! has $1 $(git_remote_branches); then
274
+ die "Remote branch '$1' does not exist and is required."
275
+ fi
276
+ }
277
+
278
+ require_branch() {
279
+ if ! has $1 $(git_all_branches); then
280
+ die "Branch '$1' does not exist and is required."
281
+ fi
282
+ }
283
+
284
+ require_branch_absent() {
285
+ if has $1 $(git_all_branches); then
286
+ die "Branch '$1' already exists. Pick another name."
287
+ fi
288
+ }
289
+
290
+ require_tag_absent() {
291
+ for tag in $(git_all_tags); do
292
+ if [ "$1" = "$tag" ]; then
293
+ die "Tag '$1' already exists. Pick another name."
294
+ fi
295
+ done
296
+ }
297
+
298
+ require_branches_equal() {
299
+ require_local_branch "$1"
300
+ require_remote_branch "$2"
301
+ git_compare_branches "$1" "$2"
302
+ local status=$?
303
+ if [ $status -gt 0 ]; then
304
+ warn "Branches '$1' and '$2' have diverged."
305
+ if [ $status -eq 1 ]; then
306
+ die "And branch '$1' may be fast-forwarded."
307
+ elif [ $status -eq 2 ]; then
308
+ # Warn here, since there is no harm in being ahead
309
+ warn "And local branch '$1' is ahead of '$2'."
310
+ else
311
+ die "Branches need merging first."
312
+ fi
313
+ fi
314
+ }
@@ -0,0 +1,4 @@
1
+ When /^I debug$/ do
2
+ debugger
3
+ end
4
+
@@ -0,0 +1,3 @@
1
+ When /^I build and install the gem$/ do
2
+ CukeGem.setup('./git_reflow.gemspec')
3
+ end