blob: 00646fed762866aa4750c031d0854ee6a67c8adc [file] [log] [blame]
Vincent Driessen186d2b52010-01-27 23:48:39 +01001#
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:
Vincent Driessenddb350b2010-07-09 09:42:09 +02006# http://nvie.com/git-model
Vincent Driessen186d2b52010-01-27 23:48:39 +01007#
8# Feel free to contribute to this project at:
9# http://github.com/nvie/gitflow
10#
Vincent Driessend72acba2010-04-04 16:10:17 +020011# 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.
Vincent Driessen186d2b52010-01-27 23:48:39 +010037#
38
39usage() {
Vincent Driessen5f860bf2011-02-05 08:22:38 +010040 echo "usage: git flow init [-fd]"
Vincent Driessen186d2b52010-01-27 23:48:39 +010041}
42
Vincent Driessen131c2982010-02-20 14:30:16 +010043parse_args() {
44 # parse options
45 FLAGS "$@" || exit $?
46 eval set -- "${FLAGS_ARGV}"
47}
48
Vincent Driessen186d2b52010-01-27 23:48:39 +010049# Default entry when no SUBACTION is given
50cmd_default() {
Vincent Driessen131c2982010-02-20 14:30:16 +010051 DEFINE_boolean force false 'force setting of gitflow branches, even if already configured' f
Vincent Driessen5f860bf2011-02-05 08:22:38 +010052 DEFINE_boolean defaults false 'use default branch naming conventions' d
Vincent Driessen131c2982010-02-20 14:30:16 +010053 parse_args "$@"
Joseph A. Levind2eccaa2011-02-04 21:30:15 -060054
Vincent Driessen283b0f72010-02-15 23:23:14 +010055 if ! git rev-parse --git-dir >/dev/null 2>&1; then
Vincent Driessen0161de52010-02-18 12:07:34 +010056 git init
57 else
Vincent Driessen131c2982010-02-20 14:30:16 +010058 # assure that we are not working in a repo with local changes
Vincent Driessen7832d6e2010-02-21 21:31:03 +010059 git_repo_is_headless || require_clean_working_tree
Vincent Driessen131c2982010-02-20 14:30:16 +010060 fi
61
62 # running git flow init on an already initialized repo is fine
63 if gitflow_is_initialized && ! flag force; then
64 warn "Already initialized for gitflow."
65 warn "To force reinitialization, use: git flow init -f"
66 exit 0
Vincent Driessen186d2b52010-01-27 23:48:39 +010067 fi
68
Vincent Driessen0161de52010-02-18 12:07:34 +010069 local branch_count
Vincent Driessenf476d262010-02-20 16:23:47 +010070 local answer
Vincent Driessen0161de52010-02-18 12:07:34 +010071
Vincent Driessenf78b6602011-02-14 07:39:23 +010072 if flag defaults; then
73 warn "Using default branch names."
74 fi
75
Vincent Driessen0161de52010-02-18 12:07:34 +010076 # add a master branch if no such branch exists yet
77 local master_branch
Vincent Driessen131c2982010-02-20 14:30:16 +010078 if gitflow_has_master_configured && ! flag force; then
79 master_branch=$(git config --get gitflow.branch.master)
80 else
81 # Two cases are distinguished:
82 # 1. A fresh git repo (without any branches)
83 # We will create a new master/develop branch for the user
84 # 2. Some branches do already exist
85 # We will disallow creation of new master/develop branches and
86 # rather allow to use existing branches for git-flow.
87 local default_suggestion
88 local should_check_existence
Vincent Driessen7832d6e2010-02-21 21:31:03 +010089 branch_count=$(git_local_branches | wc -l)
Vincent Driessen131c2982010-02-20 14:30:16 +010090 if [ "$branch_count" -eq 0 ]; then
91 echo "No branches exist yet. Base branches must be created now."
92 should_check_existence=NO
Vincent Driessenb1033aa2010-03-23 21:10:13 +010093 default_suggestion=$(git config --get gitflow.branch.master || echo master)
Vincent Driessen131c2982010-02-20 14:30:16 +010094 else
95 echo
96 echo "Which branch should be used for bringing forth production releases?"
Vincent Driessen7832d6e2010-02-21 21:31:03 +010097 git_local_branches | sed 's/^.*$/ - &/g'
Vincent Driessen131c2982010-02-20 14:30:16 +010098
99 should_check_existence=YES
100 default_suggestion=
Vincent Driessenb1033aa2010-03-23 21:10:13 +0100101 for guess in $(git config --get gitflow.branch.master) \
102 'production' 'main' 'master'; do
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100103 if git_local_branch_exists "$guess"; then
Vincent Driessen131c2982010-02-20 14:30:16 +0100104 default_suggestion="$guess"
105 break
106 fi
107 done
Vincent Driessen186d2b52010-01-27 23:48:39 +0100108 fi
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600109
Vincent Driessenf6228ed2010-03-23 21:19:54 +0100110 printf "Branch name for production releases: [$default_suggestion] "
Vincent Driessen5f860bf2011-02-05 08:22:38 +0100111 if noflag defaults; then
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600112 read answer
113 else
114 printf "\n"
115 fi
Vincent Driessen131c2982010-02-20 14:30:16 +0100116 master_branch=${answer:-$default_suggestion}
117
118 # check existence in case of an already existing repo
119 if [ "$should_check_existence" = "YES" ]; then
Eric J. Holmesbaf163e2011-11-28 23:28:47 -0800120 # if no local branch exists and a remote branch of the same
121 # name exists, checkout that branch and use it for master
122 if ! git_local_branch_exists "$master_branch" && \
123 git_remote_branch_exists "origin/$master_branch"; then
124 git branch "$master_branch" "origin/$master_branch" >/dev/null 2>&1
125 elif ! git_local_branch_exists "$master_branch"; then
Vincent Driessen131c2982010-02-20 14:30:16 +0100126 die "Local branch '$master_branch' does not exist."
Eric J. Holmesbaf163e2011-11-28 23:28:47 -0800127 fi
Vincent Driessen131c2982010-02-20 14:30:16 +0100128 fi
Vincent Driessen0161de52010-02-18 12:07:34 +0100129
Vincent Driessen61882062010-02-18 12:32:20 +0100130 # store the name of the master branch
131 git config gitflow.branch.master "$master_branch"
Vincent Driessen186d2b52010-01-27 23:48:39 +0100132 fi
133
Vincent Driessen0161de52010-02-18 12:07:34 +0100134 # add a develop branch if no such branch exists yet
135 local develop_branch
Vincent Driessen131c2982010-02-20 14:30:16 +0100136 if gitflow_has_develop_configured && ! flag force; then
137 develop_branch=$(git config --get gitflow.branch.develop)
138 else
139 # Again, the same two cases as with the master selection are
140 # considered (fresh repo or repo that contains branches)
141 local default_suggestion
142 local should_check_existence
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100143 branch_count=$(git_local_branches | grep -v "^${master_branch}\$" | wc -l)
Vincent Driessen131c2982010-02-20 14:30:16 +0100144 if [ "$branch_count" -eq 0 ]; then
145 should_check_existence=NO
Vincent Driessenb1033aa2010-03-23 21:10:13 +0100146 default_suggestion=$(git config --get gitflow.branch.develop || echo develop)
Vincent Driessen131c2982010-02-20 14:30:16 +0100147 else
148 echo
149 echo "Which branch should be used for integration of the \"next release\"?"
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100150 git_local_branches | grep -v "^${master_branch}\$" | sed 's/^.*$/ - &/g'
Vincent Driessen131c2982010-02-20 14:30:16 +0100151
152 should_check_existence=YES
153 default_suggestion=
Vincent Driessenb1033aa2010-03-23 21:10:13 +0100154 for guess in $(git config --get gitflow.branch.develop) \
155 'develop' 'int' 'integration' 'master'; do
Steve Streeting26327782012-06-05 16:26:10 -0700156 if git_local_branch_exists "$guess" && [ "$guess" != "$master_branch" ]; then
Vincent Driessen131c2982010-02-20 14:30:16 +0100157 default_suggestion="$guess"
158 break
159 fi
160 done
Steve Streeting26327782012-06-05 16:26:10 -0700161
162 if [ -z $default_suggestion ]; then
163 should_check_existence=NO
164 default_suggestion=$(git config --get gitflow.branch.develop || echo develop)
165 fi
166
Vincent Driessen0161de52010-02-18 12:07:34 +0100167 fi
Vincent Driessen131c2982010-02-20 14:30:16 +0100168
Vincent Driessenf6228ed2010-03-23 21:19:54 +0100169 printf "Branch name for \"next release\" development: [$default_suggestion] "
Vincent Driessen5f860bf2011-02-05 08:22:38 +0100170 if noflag defaults; then
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600171 read answer
172 else
173 printf "\n"
174 fi
Vincent Driessen131c2982010-02-20 14:30:16 +0100175 develop_branch=${answer:-$default_suggestion}
176
177 if [ "$master_branch" = "$develop_branch" ]; then
178 die "Production and integration branches should differ."
179 fi
180
181 # check existence in case of an already existing repo
182 if [ "$should_check_existence" = "YES" ]; then
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100183 git_local_branch_exists "$develop_branch" || \
Vincent Driessen131c2982010-02-20 14:30:16 +0100184 die "Local branch '$develop_branch' does not exist."
185 fi
Vincent Driessen0161de52010-02-18 12:07:34 +0100186
Vincent Driessen61882062010-02-18 12:32:20 +0100187 # store the name of the develop branch
188 git config gitflow.branch.develop "$develop_branch"
Vincent Driessen0161de52010-02-18 12:07:34 +0100189 fi
190
Vincent Driessen131c2982010-02-20 14:30:16 +0100191 # Creation of HEAD
192 # ----------------
193 # We create a HEAD now, if it does not exist yet (in a fresh repo). We need
194 # it to be able to create new branches.
Vincent Driessen3227d802010-02-20 16:13:23 +0100195 local created_gitflow_branch=0
Vincent Driessen0161de52010-02-18 12:07:34 +0100196 if ! git rev-parse --quiet --verify HEAD >/dev/null 2>&1; then
Vincent Driessen0161de52010-02-18 12:07:34 +0100197 git symbolic-ref HEAD "refs/heads/$master_branch"
Vincent Driessen61882062010-02-18 12:32:20 +0100198 git commit --allow-empty --quiet -m "Initial commit"
Vincent Driessen3227d802010-02-20 16:13:23 +0100199 created_gitflow_branch=1
Vincent Driessen0161de52010-02-18 12:07:34 +0100200 fi
201
Vincent Driessen131c2982010-02-20 14:30:16 +0100202 # Creation of master
203 # ------------------
204 # At this point, there always is a master branch: either it existed already
205 # (and was picked interactively as the production branch) or it has just
206 # been created in a fresh repo
207
208 # Creation of develop
209 # -------------------
210 # The develop branch possibly does not exist yet. This is the case when,
211 # in a git init'ed repo with one or more commits, master was picked as the
212 # default production branch and develop was "created". We should create
213 # the develop branch now in that case (we base it on master, of course)
Vincent Driessen7832d6e2010-02-21 21:31:03 +0100214 if ! git_local_branch_exists "$develop_branch"; then
Emre Berge Ergenekon62c339e2011-11-27 22:07:57 -0800215 if git_remote_branch_exists "origin/$develop_branch"; then
216 git branch "$develop_branch" "origin/$develop_branch" >/dev/null 2>&1
217 else
218 git branch --no-track "$develop_branch" "$master_branch"
219 fi
Vincent Driessen3227d802010-02-20 16:13:23 +0100220 created_gitflow_branch=1
Vincent Driessen0161de52010-02-18 12:07:34 +0100221 fi
222
Vincent Driessen131c2982010-02-20 14:30:16 +0100223 # assert the gitflow repo has been correctly initialized
224 gitflow_is_initialized
Vincent Driessen186d2b52010-01-27 23:48:39 +0100225
Vincent Driessen3227d802010-02-20 16:13:23 +0100226 # switch to develop branch if its newly created
227 if [ $created_gitflow_branch -eq 1 ]; then
228 git checkout -q "$develop_branch"
229 fi
Vincent Driessen61882062010-02-18 12:32:20 +0100230
Vincent Driessenf476d262010-02-20 16:23:47 +0100231 # finally, ask the user for naming conventions (branch and tag prefixes)
Vincent Driessenb1033aa2010-03-23 21:10:13 +0100232 if flag force || \
233 ! git config --get gitflow.prefix.feature >/dev/null 2>&1 ||
234 ! git config --get gitflow.prefix.release >/dev/null 2>&1 ||
235 ! git config --get gitflow.prefix.hotfix >/dev/null 2>&1 ||
236 ! git config --get gitflow.prefix.support >/dev/null 2>&1 ||
237 ! git config --get gitflow.prefix.versiontag >/dev/null 2>&1; then
238 echo
239 echo "How to name your supporting branch prefixes?"
240 fi
Vincent Driessenf476d262010-02-20 16:23:47 +0100241
242 local prefix
243
244 # Feature branches
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100245 if ! git config --get gitflow.prefix.feature >/dev/null 2>&1 || flag force; then
246 default_suggestion=$(git config --get gitflow.prefix.feature || echo feature/)
Vincent Driessenf6228ed2010-03-23 21:19:54 +0100247 printf "Feature branches? [$default_suggestion] "
Vincent Driessen5f860bf2011-02-05 08:22:38 +0100248 if noflag defaults; then
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600249 read answer
250 else
251 printf "\n"
252 fi
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100253 [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
254 git config gitflow.prefix.feature "$prefix"
255 fi
Vincent Driessenf476d262010-02-20 16:23:47 +0100256
257 # Release branches
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100258 if ! git config --get gitflow.prefix.release >/dev/null 2>&1 || flag force; then
259 default_suggestion=$(git config --get gitflow.prefix.release || echo release/)
Vincent Driessenf6228ed2010-03-23 21:19:54 +0100260 printf "Release branches? [$default_suggestion] "
Vincent Driessen5f860bf2011-02-05 08:22:38 +0100261 if noflag defaults; then
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600262 read answer
263 else
264 printf "\n"
265 fi
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100266 [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
267 git config gitflow.prefix.release "$prefix"
268 fi
269
Vincent Driessenf476d262010-02-20 16:23:47 +0100270
271 # Hotfix branches
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100272 if ! git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || flag force; then
273 default_suggestion=$(git config --get gitflow.prefix.hotfix || echo hotfix/)
Vincent Driessenf6228ed2010-03-23 21:19:54 +0100274 printf "Hotfix branches? [$default_suggestion] "
Vincent Driessen5f860bf2011-02-05 08:22:38 +0100275 if noflag defaults; then
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600276 read answer
277 else
278 printf "\n"
279 fi
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100280 [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
281 git config gitflow.prefix.hotfix "$prefix"
282 fi
283
Vincent Driessenf476d262010-02-20 16:23:47 +0100284
285 # Support branches
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100286 if ! git config --get gitflow.prefix.support >/dev/null 2>&1 || flag force; then
287 default_suggestion=$(git config --get gitflow.prefix.support || echo support/)
Vincent Driessenf6228ed2010-03-23 21:19:54 +0100288 printf "Support branches? [$default_suggestion] "
Vincent Driessen5f860bf2011-02-05 08:22:38 +0100289 if noflag defaults; then
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600290 read answer
291 else
292 printf "\n"
293 fi
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100294 [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
295 git config gitflow.prefix.support "$prefix"
296 fi
297
Vincent Driessenf476d262010-02-20 16:23:47 +0100298
299 # Version tag prefix
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100300 if ! git config --get gitflow.prefix.versiontag >/dev/null 2>&1 || flag force; then
301 default_suggestion=$(git config --get gitflow.prefix.versiontag || echo "")
Vincent Driessenf6228ed2010-03-23 21:19:54 +0100302 printf "Version tag prefix? [$default_suggestion] "
Vincent Driessen5f860bf2011-02-05 08:22:38 +0100303 if noflag defaults; then
Joseph A. Levind2eccaa2011-02-04 21:30:15 -0600304 read answer
305 else
306 printf "\n"
307 fi
Vincent Driessen1d8bb0d2010-02-20 16:46:38 +0100308 [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
309 git config gitflow.prefix.versiontag "$prefix"
310 fi
311
Vincent Driessen61882062010-02-18 12:32:20 +0100312
313 # TODO: what to do with origin?
Vincent Driessen186d2b52010-01-27 23:48:39 +0100314}
315
Vincent Driessenb866b012010-01-28 01:01:53 +0100316cmd_help() {
317 usage
318 exit 0
319}