git-scripts 0.1.0
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/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
|