git-scripts 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +21 -0
- data/README.md +124 -0
- data/Rakefile +35 -0
- data/bash_completion.sh +33 -0
- data/bin/feature +191 -0
- data/bin/hotfix +142 -0
- data/lib/git.rb +170 -0
- data/lib/github.rb +190 -0
- data/lib/helpers.rb +137 -0
- data/man/feature-clean.1 +28 -0
- data/man/feature-clean.1.html +115 -0
- data/man/feature-clean.1.markdown +53 -0
- data/man/feature-clean.1.ronn +26 -0
- data/man/feature-finish.1 +19 -0
- data/man/feature-finish.1.html +107 -0
- data/man/feature-finish.1.markdown +47 -0
- data/man/feature-finish.1.ronn +21 -0
- data/man/feature-github-test.1 +19 -0
- data/man/feature-github-test.1.html +105 -0
- data/man/feature-github-test.1.markdown +45 -0
- data/man/feature-github-test.1.ronn +19 -0
- data/man/feature-list.1 +19 -0
- data/man/feature-list.1.html +106 -0
- data/man/feature-list.1.markdown +46 -0
- data/man/feature-list.1.ronn +20 -0
- data/man/feature-merge.1 +22 -0
- data/man/feature-merge.1.html +110 -0
- data/man/feature-merge.1.markdown +50 -0
- data/man/feature-merge.1.ronn +24 -0
- data/man/feature-start.1 +19 -0
- data/man/feature-start.1.html +105 -0
- data/man/feature-start.1.markdown +45 -0
- data/man/feature-start.1.ronn +19 -0
- data/man/feature-stashes.1 +28 -0
- data/man/feature-stashes.1.html +117 -0
- data/man/feature-stashes.1.markdown +55 -0
- data/man/feature-stashes.1.ronn +28 -0
- data/man/feature-status.1 +22 -0
- data/man/feature-status.1.html +108 -0
- data/man/feature-status.1.markdown +48 -0
- data/man/feature-status.1.ronn +22 -0
- data/man/feature-switch.1 +25 -0
- data/man/feature-switch.1.html +113 -0
- data/man/feature-switch.1.markdown +51 -0
- data/man/feature-switch.1.ronn +24 -0
- data/man/feature.1 +61 -0
- data/man/feature.1.html +123 -0
- data/man/feature.1.markdown +70 -0
- data/man/feature.1.ronn +43 -0
- data/man/feature.html +140 -0
- data/man/hotfix-finish.1 +19 -0
- data/man/hotfix-finish.1.html +107 -0
- data/man/hotfix-finish.1.markdown +47 -0
- data/man/hotfix-finish.1.ronn +21 -0
- data/man/hotfix-list.1 +19 -0
- data/man/hotfix-list.1.html +106 -0
- data/man/hotfix-list.1.markdown +46 -0
- data/man/hotfix-list.1.ronn +20 -0
- data/man/hotfix-merge.1 +22 -0
- data/man/hotfix-merge.1.html +110 -0
- data/man/hotfix-merge.1.markdown +50 -0
- data/man/hotfix-merge.1.ronn +24 -0
- data/man/hotfix-start.1 +19 -0
- data/man/hotfix-start.1.html +105 -0
- data/man/hotfix-start.1.markdown +45 -0
- data/man/hotfix-start.1.ronn +19 -0
- data/man/hotfix-switch.1 +19 -0
- data/man/hotfix-switch.1.html +105 -0
- data/man/hotfix-switch.1.markdown +45 -0
- data/man/hotfix-switch.1.ronn +19 -0
- data/man/hotfix.1 +41 -0
- data/man/hotfix.1.html +118 -0
- data/man/hotfix.1.markdown +60 -0
- data/man/hotfix.1.ronn +33 -0
- data/man/index.html +7 -0
- data/man/index.txt +21 -0
- metadata +177 -0
data/COPYING
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
Copyright (c) 2012-2013 iFixit
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
|
+
this software and associated documentation files (the "Software"), to deal in
|
6
|
+
the Software without restriction, including without limitation the rights to
|
7
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
8
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
9
|
+
so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
12
|
+
copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
SOFTWARE.
|
21
|
+
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# Git Scripts
|
2
|
+
|
3
|
+
User scripts for easily managing feature branches and hotfixes.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
```bash
|
7
|
+
gem install git-scripts
|
8
|
+
```
|
9
|
+
|
10
|
+
or
|
11
|
+
|
12
|
+
```bash
|
13
|
+
git clone git://github.com/iFixit/git-scripts.git
|
14
|
+
cd git-scripts
|
15
|
+
bundle install
|
16
|
+
ln -s ${PWD}/bin/feature /path/to/bin/dir/
|
17
|
+
ln -s ${PWD}/bin/hotfix /path/to/bin/dir/
|
18
|
+
```
|
19
|
+
|
20
|
+
## Branching Model
|
21
|
+
|
22
|
+
This is loosely based on the [Git Flow][gitflow] branching model, with a couple
|
23
|
+
of noteable changes. Essentially Git Flow's `develop` is our `master`, Git
|
24
|
+
Flow's `master` is our `stable`, and there are no `release` branches and our
|
25
|
+
`hotfix` branch names all have a prefix.
|
26
|
+
|
27
|
+
**master** is the active development branch, and what our development server
|
28
|
+
has checked out. This is configurable using: `git config
|
29
|
+
feature.development_branch branch-name`
|
30
|
+
|
31
|
+
**stable** is the branch which is deployed on the production machines. You
|
32
|
+
should always be able to check out this branch and get "bug-free" production
|
33
|
+
code. This branch is always ready-to-go and should always be deployed as soon
|
34
|
+
as it's changed
|
35
|
+
|
36
|
+
**feature branches** are named after the feature you're developing and branched
|
37
|
+
from `master`. When finished, the feature branch is merged back into master
|
38
|
+
with `--no-ff` (so we preserve the merge commit) and deleted.
|
39
|
+
|
40
|
+
**hotfix branches** are named `hotfix-name` and branched from `stable`. When
|
41
|
+
finished, the hotfix branch is merged back into `stable` with `--no-ff` so we
|
42
|
+
preserve the merge commit. We attempt to merge it back into `master` as well,
|
43
|
+
but if it's going to get messy just bail.
|
44
|
+
|
45
|
+
## Deployment
|
46
|
+
|
47
|
+
The production machines always run off the `stable` branch. When deploying,
|
48
|
+
you need to:
|
49
|
+
|
50
|
+
* Merge `stable` into `master` (and vice-versa). This ensures that the two code
|
51
|
+
paths come together relatively frequently. This also guarantees that we'll
|
52
|
+
pick up any stray hotfixes that didn't get merged back.
|
53
|
+
|
54
|
+
* Create a tag on `stable` for keeping track of deploys
|
55
|
+
|
56
|
+
## feature script
|
57
|
+
|
58
|
+
feature <command> [branch name]
|
59
|
+
|
60
|
+
Automates some of the git commands for dealing with feature branches. Any
|
61
|
+
command that is run with missing arguments will just print the help and exit.
|
62
|
+
Any command that modifies the working dir should warn the user and exit(1) if
|
63
|
+
the working tree is dirty; automatically managing the stash is frought with
|
64
|
+
danger.
|
65
|
+
|
66
|
+
feature start my-awesome-thing
|
67
|
+
|
68
|
+
If the branch `my-awesome-thing` does not exist, a new feature branch
|
69
|
+
from `master` will be created after a confirmation, and runs a
|
70
|
+
`git checkout my-awesome-thing` to drop you on the new branch.
|
71
|
+
|
72
|
+
feature switch your-neato-thing
|
73
|
+
|
74
|
+
Assuming the branch `your-neato-thing` exists, it checks out that branch and
|
75
|
+
informs you about any stashes saved on that branch.
|
76
|
+
|
77
|
+
feature finish [your-neato-thing]
|
78
|
+
|
79
|
+
Creates a pull-request on Github for the current or specified feature branch.
|
80
|
+
|
81
|
+
feature merge [your-neato-thing]
|
82
|
+
|
83
|
+
Merges the feature branch back in to `master`, using `--no-ff` to ensure it's a
|
84
|
+
non-fast-forward merge. This attempts to get a pull request description from
|
85
|
+
the github API.
|
86
|
+
|
87
|
+
feature status
|
88
|
+
|
89
|
+
Shows a graphical commit log of the history between the current branch and the
|
90
|
+
remote version of the current branch (the upstream).
|
91
|
+
|
92
|
+
feature stashes
|
93
|
+
|
94
|
+
Lists the stashes saved on the current branch if any. -v shows all stashes on
|
95
|
+
all branches.
|
96
|
+
|
97
|
+
## hotfix script
|
98
|
+
|
99
|
+
hotfix <command> [branch name]
|
100
|
+
|
101
|
+
Automates the process of fixing a bug on the live site, similar to the
|
102
|
+
`feature` script with a few differences. Any command that is run with missing
|
103
|
+
arguments will just print the help and exit
|
104
|
+
|
105
|
+
hotfix start my-sweet-fix
|
106
|
+
|
107
|
+
Makes a new branch from `stable` named `hotfix_my-sweet-fix`. Prepending the
|
108
|
+
name with `hotfix_` allows easy filtering.
|
109
|
+
|
110
|
+
hotfix switch my-other-fix
|
111
|
+
|
112
|
+
Switches hotfix branches. Assuming the branch `hotfix_my-other-fix` exists, it
|
113
|
+
checks out that branch and informs you about any stashes saved on that branch.
|
114
|
+
|
115
|
+
hotfix finish [my-other-fix]
|
116
|
+
|
117
|
+
Creates a pull-request on Github for the current or specified hotfix branch.
|
118
|
+
|
119
|
+
hotfix merge [my-other-fix]
|
120
|
+
|
121
|
+
Merges the hotfix branch back into `stable` with `--no-ff`. Also does a
|
122
|
+
merge back into `master`.
|
123
|
+
|
124
|
+
[gitflow]: http://nvie.com/posts/a-successful-git-branching-model/
|
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'mg'
|
2
|
+
MG.new 'git-scripts.gemspec'
|
3
|
+
|
4
|
+
desc 'Build the manual'
|
5
|
+
task :man do
|
6
|
+
require 'ronn'
|
7
|
+
ENV['RONN_ORGANIZATION'] = 'iFixit'
|
8
|
+
sh "ronn -w -s toc -r5 --markdown man/*.ronn"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Publish to github pages'
|
12
|
+
task :pages => :man do
|
13
|
+
puts '----------------------------------------------'
|
14
|
+
puts 'Rebuilding pages ...'
|
15
|
+
verbose(false) {
|
16
|
+
rm_rf 'pages'
|
17
|
+
push_url = `git remote show origin`.each_line.grep(/Push.*URL/).first[/git@.*/]
|
18
|
+
sh "
|
19
|
+
set -ex
|
20
|
+
git fetch -q origin
|
21
|
+
rev=$(git rev-parse origin/gh-pages)
|
22
|
+
git clone -q -b gh-pages . pages
|
23
|
+
cd pages
|
24
|
+
git reset --hard $rev
|
25
|
+
rm -f *
|
26
|
+
cp -rp ../man/*.html ../man/index.txt ./
|
27
|
+
git add -A .
|
28
|
+
git commit -m 'Rebuild manual.'
|
29
|
+
git push #{push_url} gh-pages
|
30
|
+
cd ..
|
31
|
+
rm -rf pages
|
32
|
+
", :verbose => false
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
data/bash_completion.sh
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
_git-scripts()
|
4
|
+
{
|
5
|
+
local cmd="${1##*/}"
|
6
|
+
local cur=${COMP_WORDS[COMP_CWORD]}
|
7
|
+
local line=${COMP_LINE}
|
8
|
+
|
9
|
+
# Check to see what command is being executed.
|
10
|
+
case "$cmd" in
|
11
|
+
feature)
|
12
|
+
if [ "$line" = "$cmd $cur" ]; then
|
13
|
+
words="switch start finish stashes list merge pull status clean"
|
14
|
+
else
|
15
|
+
# get branch names minus hotfixes
|
16
|
+
words="$(git branch -a | tr -d ' *' | grep -v 'hotfix-' | sed 's|remotes/origin/||')"
|
17
|
+
fi
|
18
|
+
;;
|
19
|
+
hotfix)
|
20
|
+
if [ "$line" = "$cmd $cur" ]; then
|
21
|
+
words="switch start finish merge list clean"
|
22
|
+
else
|
23
|
+
# get hotfix branch names
|
24
|
+
words="$(git branch -a | tr -d ' *' | grep 'hotfix-' | sed -e 's|remotes/origin/||' -e 's|hotfix-||')"
|
25
|
+
fi
|
26
|
+
;;
|
27
|
+
esac
|
28
|
+
|
29
|
+
COMPREPLY=($(compgen -W "${words}" -- ${cur}))
|
30
|
+
return 0
|
31
|
+
}
|
32
|
+
|
33
|
+
complete -F _git-scripts feature hotfix
|
data/bin/feature
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../lib/github.rb'
|
3
|
+
require_relative '../lib/git.rb'
|
4
|
+
require_relative '../lib/helpers.rb'
|
5
|
+
|
6
|
+
command=ARGV.first
|
7
|
+
|
8
|
+
case command
|
9
|
+
when 'github-test'
|
10
|
+
octokit = Github::api
|
11
|
+
# Should succeed if authentication is setup.
|
12
|
+
octokit.pulls(Github::get_github_repo)
|
13
|
+
puts "[Successfully Authenticated]"
|
14
|
+
|
15
|
+
when 'start'
|
16
|
+
require_argument(:feature, :start)
|
17
|
+
feature = ARGV[1]
|
18
|
+
|
19
|
+
exit if !confirm("Create feature branch named: '#{feature}' ?")
|
20
|
+
|
21
|
+
Git::run_safe("git checkout #{Git::development_branch}")
|
22
|
+
Git::run_safe("git pull --rebase")
|
23
|
+
Git::run_safe("git branch \"#{feature}\" #{Git::development_branch}")
|
24
|
+
Git::run_safe("git checkout \"#{feature}\"")
|
25
|
+
|
26
|
+
Git::submodules_update
|
27
|
+
|
28
|
+
# Automatically setup remote tracking branch
|
29
|
+
Git::run_safe("git config branch.#{feature}.remote origin")
|
30
|
+
Git::run_safe("git config branch.#{feature}.merge refs/heads/#{feature}")
|
31
|
+
Git::run_safe("git config branch.#{feature}.rebase true")
|
32
|
+
|
33
|
+
puts "Successfully created a new feature-branch: #{feature}"
|
34
|
+
|
35
|
+
when 'status'
|
36
|
+
current = Git::current_branch
|
37
|
+
Git::run_safe("git fetch")
|
38
|
+
|
39
|
+
upstream = `git rev-parse --verify --quiet #{current}@{upstream} 2>/dev/null`.strip
|
40
|
+
if upstream == ''
|
41
|
+
die "Your branch #{current} hasn't been pushed"
|
42
|
+
end
|
43
|
+
|
44
|
+
git_command = 'git log --graph --boundary --color=always --decorate --date-order'
|
45
|
+
incoming = `#{git_command} #{current}..#{upstream}`.strip
|
46
|
+
outgoing = `#{git_command} #{upstream}..#{current}`.strip
|
47
|
+
incoming = nil if incoming == ''
|
48
|
+
outgoing = nil if outgoing == ''
|
49
|
+
|
50
|
+
if (incoming && outgoing)
|
51
|
+
# Show the whole history graph (... == through common ancestor)
|
52
|
+
puts `#{git_command} #{upstream}...#{current}`.strip
|
53
|
+
puts HIGHLIGHT
|
54
|
+
puts "Your branch has diverged from the remote branch"
|
55
|
+
elsif incoming
|
56
|
+
puts incoming
|
57
|
+
puts HIGHLIGHT
|
58
|
+
puts "Your branch is behind the remote branch"
|
59
|
+
elsif outgoing
|
60
|
+
puts outgoing
|
61
|
+
puts HIGHLIGHT
|
62
|
+
puts "Your branch is ahead of the remote branch"
|
63
|
+
else
|
64
|
+
puts HIGHLIGHT
|
65
|
+
puts "Your branch is up to date"
|
66
|
+
end
|
67
|
+
print HIGHLIGHT_OFF
|
68
|
+
|
69
|
+
|
70
|
+
when 'finish'
|
71
|
+
feature = ARGV[1] || Git::current_branch
|
72
|
+
# Push commits to origin
|
73
|
+
Git::run_safe("git push origin #{feature}:#{feature}")
|
74
|
+
|
75
|
+
exit 1 if !confirm("Create a pull-request for feature branch named: '#{feature}' ?")
|
76
|
+
octokit = Github::api
|
77
|
+
|
78
|
+
description = Github::get_pull_request_description(feature)
|
79
|
+
puts "Pull-request description:"
|
80
|
+
puts description[:title]
|
81
|
+
puts "#"
|
82
|
+
puts description[:body]
|
83
|
+
|
84
|
+
response = octokit.create_pull_request(
|
85
|
+
Github::get_github_repo,
|
86
|
+
Git::development_branch,
|
87
|
+
feature,
|
88
|
+
description[:title],
|
89
|
+
description[:body]
|
90
|
+
)
|
91
|
+
|
92
|
+
puts "Successfully created pull-request ##{response[:number]}"
|
93
|
+
puts " " + response[:html_url]
|
94
|
+
|
95
|
+
when 'merge'
|
96
|
+
dev_branch = Git::development_branch
|
97
|
+
fail_on_local_changes
|
98
|
+
Git::run_safe("git fetch")
|
99
|
+
|
100
|
+
feature = ARGV[1] || Git::current_branch
|
101
|
+
|
102
|
+
exit 1 if !confirm("Merge feature branch named: '#{feature}' ?")
|
103
|
+
|
104
|
+
description = Github::get_pull_request_description_from_api(feature, dev_branch)
|
105
|
+
|
106
|
+
# Checkout the branch first to make sure we have it locally.
|
107
|
+
Git::run_safe("git fetch")
|
108
|
+
Git::run_safe("git checkout \"#{feature}\"")
|
109
|
+
|
110
|
+
Git::run_safe("git rebase --preserve-merges origin/#{feature}")
|
111
|
+
|
112
|
+
# pull the latest changes from master
|
113
|
+
Git::run_safe("git checkout #{dev_branch}")
|
114
|
+
|
115
|
+
# rebase the unpushed master commits if any.
|
116
|
+
Git::run_safe("git rebase --preserve-merges origin/#{dev_branch}")
|
117
|
+
|
118
|
+
# merge the feature branch into master
|
119
|
+
Git::run_safe("git merge --no-ff --edit -m #{description.shellescape} \"#{feature}\"")
|
120
|
+
|
121
|
+
# init any submodules in the master branch
|
122
|
+
Git::submodules_update
|
123
|
+
|
124
|
+
# delete the local feature-branch
|
125
|
+
Git::run_safe("git branch -d \"#{feature}\"")
|
126
|
+
|
127
|
+
# delete the remote branch we'll leave this off for now
|
128
|
+
# Git::run_safe("git push origin :\"#{feature}\"")
|
129
|
+
# push the the merge to our origin
|
130
|
+
# Git::run_safe("git push origin")
|
131
|
+
|
132
|
+
puts
|
133
|
+
puts "Successfully merged feature-branch: #{feature} into #{dev_branch}"
|
134
|
+
|
135
|
+
when 'switch'
|
136
|
+
require_argument(:feature, :switch, min=2, max=3)
|
137
|
+
feature = ARGV[1]
|
138
|
+
|
139
|
+
Git::switch_branch(feature)
|
140
|
+
|
141
|
+
when 'clean'
|
142
|
+
args = ''
|
143
|
+
|
144
|
+
# Remove all untracked .gitignored files as well
|
145
|
+
args += 'x' if ARGV.include?('--all')
|
146
|
+
|
147
|
+
# -fd alone will NOT remove submodule directories, -ffd is required for this
|
148
|
+
Git::run_safe("git clean -ffd#{args}")
|
149
|
+
|
150
|
+
when 'pull'
|
151
|
+
Git::run_safe("git fetch")
|
152
|
+
|
153
|
+
current = Git::current_branch
|
154
|
+
upstream = "#{current}@{upstream}"
|
155
|
+
upstream_hash = Git::branch_hash(upstream)
|
156
|
+
|
157
|
+
if upstream_hash == ''
|
158
|
+
die "Your branch #{current} hasn't been pushed, nothing to pull from"
|
159
|
+
end
|
160
|
+
|
161
|
+
old_branch_hash = Git::branch_hash(current)
|
162
|
+
Git::run_safe("git rebase --preserve-merges origin/#{current}")
|
163
|
+
|
164
|
+
Git::submodules_update
|
165
|
+
|
166
|
+
if Git::branch_hash(current) == old_branch_hash
|
167
|
+
die "No changes in the remote branch. Your branch is up to date."
|
168
|
+
end
|
169
|
+
|
170
|
+
when 'list'
|
171
|
+
options = {
|
172
|
+
:feature => Git::feature_branches(:unmerged)
|
173
|
+
}
|
174
|
+
if ARGV.include?('-v')
|
175
|
+
options[:merged] = Git::feature_branches(:merged)
|
176
|
+
end
|
177
|
+
Git.show_branch_list(options)
|
178
|
+
|
179
|
+
when 'stashes'
|
180
|
+
current_branch = nil
|
181
|
+
|
182
|
+
if !ARGV.include?('-v')
|
183
|
+
current_branch = Git::current_branch
|
184
|
+
end
|
185
|
+
|
186
|
+
Git::show_stashes_saved_on(current_branch)
|
187
|
+
|
188
|
+
else
|
189
|
+
display_feature_help
|
190
|
+
end
|
191
|
+
|
data/bin/hotfix
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../lib/github.rb'
|
3
|
+
require_relative '../lib/git.rb'
|
4
|
+
require_relative '../lib/helpers.rb'
|
5
|
+
|
6
|
+
command=ARGV.first
|
7
|
+
BRANCH_PREFIX = "hotfix-"
|
8
|
+
case command
|
9
|
+
when 'start'
|
10
|
+
require_argument(:hotfix, :start)
|
11
|
+
hotfix = BRANCH_PREFIX + ARGV[1]
|
12
|
+
|
13
|
+
exit if !confirm("Create hotfix branch named: '#{hotfix}' ?")
|
14
|
+
|
15
|
+
Git::run_safe("git checkout stable")
|
16
|
+
Git::run_safe("git pull --rebase")
|
17
|
+
Git::run_safe("git branch \"#{hotfix}\" stable")
|
18
|
+
Git::run_safe("git checkout \"#{hotfix}\"")
|
19
|
+
|
20
|
+
Git::submodules_update
|
21
|
+
|
22
|
+
# Automatically setup remote tracking branch
|
23
|
+
Git::run_safe("git config branch.#{hotfix}.remote origin")
|
24
|
+
Git::run_safe("git config branch.#{hotfix}.merge refs/heads/#{hotfix}")
|
25
|
+
Git::run_safe("git config branch.#{hotfix}.rebase true")
|
26
|
+
|
27
|
+
when 'switch'
|
28
|
+
require_argument(:hotfix, :switch, min=2, max=3)
|
29
|
+
hotfix = BRANCH_PREFIX + ARGV[1]
|
30
|
+
|
31
|
+
Git::switch_branch(hotfix)
|
32
|
+
|
33
|
+
when 'finish'
|
34
|
+
hotfix = ARGV[1] || Git::current_branch
|
35
|
+
|
36
|
+
# ensure the hotfix name is the real branch name
|
37
|
+
if (!hotfix.start_with?("hotfix-"))
|
38
|
+
hotfix = "hotfix-" + hotfix
|
39
|
+
end
|
40
|
+
|
41
|
+
# Push commits to origin
|
42
|
+
Git::run_safe("git push origin #{hotfix}:#{hotfix}")
|
43
|
+
|
44
|
+
exit 1 if !confirm("Create a pull-request for hotfix branch named: '#{hotfix}' ?")
|
45
|
+
octokit = Github::api
|
46
|
+
|
47
|
+
description = Github::get_pull_request_description(hotfix)
|
48
|
+
puts "Pull-request description:"
|
49
|
+
puts description[:title]
|
50
|
+
puts "#"
|
51
|
+
puts description[:body]
|
52
|
+
|
53
|
+
response = octokit.create_pull_request(
|
54
|
+
Github::get_github_repo,
|
55
|
+
'stable',
|
56
|
+
hotfix,
|
57
|
+
description[:title],
|
58
|
+
description[:body]
|
59
|
+
)
|
60
|
+
|
61
|
+
puts "Successfully created pull-request ##{response[:number]}"
|
62
|
+
puts " " + response[:html_url]
|
63
|
+
|
64
|
+
when 'merge'
|
65
|
+
fail_on_local_changes
|
66
|
+
dev_branch = Git::development_branch
|
67
|
+
|
68
|
+
Git::run_safe("git fetch")
|
69
|
+
|
70
|
+
if ARGV[1]
|
71
|
+
hotfix = BRANCH_PREFIX + ARGV[1]
|
72
|
+
else
|
73
|
+
hotfix = Git::current_branch
|
74
|
+
end
|
75
|
+
|
76
|
+
exit 1 if !confirm("Merge hotfix named: '#{hotfix}' ?")
|
77
|
+
|
78
|
+
description = Github::get_pull_request_description_from_api(hotfix, 'stable')
|
79
|
+
|
80
|
+
# Checkout the branch to make sure we have it locally.
|
81
|
+
Git::run_safe("git checkout \"#{hotfix}\"")
|
82
|
+
Git::run_safe("git rebase --preserve-merges origin/#{hotfix}")
|
83
|
+
|
84
|
+
# Merge into stable
|
85
|
+
Git::run_safe("git checkout stable")
|
86
|
+
|
87
|
+
# pull the latest changes and rebase the unpushed commits if any.
|
88
|
+
Git::run_safe("git rebase --preserve-merges origin/stable")
|
89
|
+
|
90
|
+
# merge the hotfix branch into stable
|
91
|
+
Git::run_safe("git merge --no-ff --edit -m #{description.shellescape} \"#{hotfix}\"")
|
92
|
+
|
93
|
+
# init any submodules in the stable branch
|
94
|
+
Git::submodules_update
|
95
|
+
# push the the merge to our origin
|
96
|
+
# Git::run_safe("git push origin")
|
97
|
+
|
98
|
+
description = Github::get_pull_request_description_from_api(hotfix, dev_branch)
|
99
|
+
|
100
|
+
# Merge into master
|
101
|
+
Git::run_safe("git checkout #{dev_branch}")
|
102
|
+
|
103
|
+
# pull the latest changes and rebase the unpushed master commits if any.
|
104
|
+
Git::run_safe("git rebase origin/#{dev_branch}")
|
105
|
+
|
106
|
+
# merge the hotfix branch into master
|
107
|
+
Git::run_safe("git merge --no-ff --edit -m #{description.shellescape} \"#{hotfix}\"")
|
108
|
+
|
109
|
+
# init any submodules in the master branch. Note: no need to change
|
110
|
+
# directories before calling git submodule since we are already in the
|
111
|
+
# projects top-level directory
|
112
|
+
Git::submodules_update
|
113
|
+
|
114
|
+
# push the the merge to our origin
|
115
|
+
# Git::run_safe("git push origin")
|
116
|
+
|
117
|
+
# delete the local hotfix branch
|
118
|
+
Git::run_safe("git branch -d \"#{hotfix}\"")
|
119
|
+
# delete the remote hotfix branch -- we'll leave this off for now
|
120
|
+
# Git::run_safe("git push origin :\"#{hotfix}\"")
|
121
|
+
|
122
|
+
# checkout stable branch
|
123
|
+
Git::run_safe("git checkout stable")
|
124
|
+
|
125
|
+
puts "Successfully merged hotfix branch: #{hotfix} into stable and #{dev_branch}"
|
126
|
+
puts "If you are satisfied with the result, do this:\n" + <<CMDS
|
127
|
+
git push
|
128
|
+
git checkout #{dev_branch}
|
129
|
+
git push
|
130
|
+
CMDS
|
131
|
+
|
132
|
+
when 'list'
|
133
|
+
options = {
|
134
|
+
:hotfix => Git::hotfix_branches(:unmerged)
|
135
|
+
}
|
136
|
+
if ARGV.include?('-v')
|
137
|
+
options[:merged] = Git::hotfix_branches(:merged)
|
138
|
+
end
|
139
|
+
Git.show_branch_list(options)
|
140
|
+
else
|
141
|
+
display_hotfix_help
|
142
|
+
end
|