| # |
| # git-flow -- A collection of Git extensions to provide high-level |
| # repository operations for Vincent Driessen's branching model. |
| # |
| # Original blog post presenting this model is found at: |
| # http://nvie.com/git-model |
| # |
| # Feel free to contribute to this project at: |
| # http://github.com/nvie/gitflow |
| # |
| # Copyright 2010 Vincent Driessen. All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are met: |
| # |
| # 1. Redistributions of source code must retain the above copyright notice, |
| # this list of conditions and the following disclaimer. |
| # |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY VINCENT DRIESSEN ``AS IS'' AND ANY EXPRESS OR |
| # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| # EVENT SHALL VINCENT DRIESSEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
| # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| # |
| # The views and conclusions contained in the software and documentation are |
| # those of the authors and should not be interpreted as representing official |
| # policies, either expressed or implied, of Vincent Driessen. |
| # |
| |
| usage() { |
| echo "usage: git flow init [-fd]" |
| } |
| |
| parse_args() { |
| # parse options |
| FLAGS "$@" || exit $? |
| eval set -- "${FLAGS_ARGV}" |
| } |
| |
| # Default entry when no SUBACTION is given |
| cmd_default() { |
| DEFINE_boolean force false 'force setting of gitflow branches, even if already configured' f |
| DEFINE_boolean defaults false 'use default branch naming conventions' d |
| parse_args "$@" |
| |
| if ! git rev-parse --git-dir >/dev/null 2>&1; then |
| git init |
| else |
| # assure that we are not working in a repo with local changes |
| git_repo_is_headless || require_clean_working_tree |
| fi |
| |
| # running git flow init on an already initialized repo is fine |
| if gitflow_is_initialized && ! flag force; then |
| warn "Already initialized for gitflow." |
| warn "To force reinitialization, use: git flow init -f" |
| exit 0 |
| fi |
| |
| local branch_count |
| local answer |
| |
| if flag defaults; then |
| warn "Using default branch names." |
| fi |
| |
| # add a master branch if no such branch exists yet |
| local master_branch |
| if gitflow_has_master_configured && ! flag force; then |
| master_branch=$(git config --get gitflow.branch.master) |
| else |
| # Two cases are distinguished: |
| # 1. A fresh git repo (without any branches) |
| # We will create a new master/develop branch for the user |
| # 2. Some branches do already exist |
| # We will disallow creation of new master/develop branches and |
| # rather allow to use existing branches for git-flow. |
| local default_suggestion |
| local should_check_existence |
| branch_count=$(git_local_branches | wc -l) |
| if [ "$branch_count" -eq 0 ]; then |
| echo "No branches exist yet. Base branches must be created now." |
| should_check_existence=NO |
| default_suggestion=$(git config --get gitflow.branch.master || echo master) |
| else |
| echo |
| echo "Which branch should be used for bringing forth production releases?" |
| git_local_branches | sed 's/^.*$/ - &/g' |
| |
| should_check_existence=YES |
| default_suggestion= |
| for guess in $(git config --get gitflow.branch.master) \ |
| 'production' 'main' 'master'; do |
| if git_local_branch_exists "$guess"; then |
| default_suggestion="$guess" |
| break |
| fi |
| done |
| fi |
| |
| printf "Branch name for production releases: [$default_suggestion] " |
| if noflag defaults; then |
| read answer |
| else |
| printf "\n" |
| fi |
| master_branch=${answer:-$default_suggestion} |
| |
| # check existence in case of an already existing repo |
| if [ "$should_check_existence" = "YES" ]; then |
| git_local_branch_exists "$master_branch" || \ |
| die "Local branch '$master_branch' does not exist." |
| fi |
| |
| # store the name of the master branch |
| git config gitflow.branch.master "$master_branch" |
| fi |
| |
| # add a develop branch if no such branch exists yet |
| local develop_branch |
| if gitflow_has_develop_configured && ! flag force; then |
| develop_branch=$(git config --get gitflow.branch.develop) |
| else |
| # Again, the same two cases as with the master selection are |
| # considered (fresh repo or repo that contains branches) |
| local default_suggestion |
| local should_check_existence |
| branch_count=$(git_local_branches | grep -v "^${master_branch}\$" | wc -l) |
| if [ "$branch_count" -eq 0 ]; then |
| should_check_existence=NO |
| default_suggestion=$(git config --get gitflow.branch.develop || echo develop) |
| else |
| echo |
| echo "Which branch should be used for integration of the \"next release\"?" |
| git_local_branches | grep -v "^${master_branch}\$" | sed 's/^.*$/ - &/g' |
| |
| should_check_existence=YES |
| default_suggestion= |
| for guess in $(git config --get gitflow.branch.develop) \ |
| 'develop' 'int' 'integration' 'master'; do |
| if git_local_branch_exists "$guess"; then |
| default_suggestion="$guess" |
| break |
| fi |
| done |
| fi |
| |
| printf "Branch name for \"next release\" development: [$default_suggestion] " |
| if noflag defaults; then |
| read answer |
| else |
| printf "\n" |
| fi |
| develop_branch=${answer:-$default_suggestion} |
| |
| if [ "$master_branch" = "$develop_branch" ]; then |
| die "Production and integration branches should differ." |
| fi |
| |
| # check existence in case of an already existing repo |
| if [ "$should_check_existence" = "YES" ]; then |
| git_local_branch_exists "$develop_branch" || \ |
| die "Local branch '$develop_branch' does not exist." |
| fi |
| |
| # store the name of the develop branch |
| git config gitflow.branch.develop "$develop_branch" |
| fi |
| |
| # Creation of HEAD |
| # ---------------- |
| # We create a HEAD now, if it does not exist yet (in a fresh repo). We need |
| # it to be able to create new branches. |
| local created_gitflow_branch=0 |
| if ! git rev-parse --quiet --verify HEAD >/dev/null 2>&1; then |
| git symbolic-ref HEAD "refs/heads/$master_branch" |
| git commit --allow-empty --quiet -m "Initial commit" |
| created_gitflow_branch=1 |
| fi |
| |
| # Creation of master |
| # ------------------ |
| # At this point, there always is a master branch: either it existed already |
| # (and was picked interactively as the production branch) or it has just |
| # been created in a fresh repo |
| |
| # Creation of develop |
| # ------------------- |
| # The develop branch possibly does not exist yet. This is the case when, |
| # in a git init'ed repo with one or more commits, master was picked as the |
| # default production branch and develop was "created". We should create |
| # the develop branch now in that case (we base it on master, of course) |
| if ! git_local_branch_exists "$develop_branch"; then |
| git branch --no-track "$develop_branch" "$master_branch" |
| created_gitflow_branch=1 |
| fi |
| |
| # assert the gitflow repo has been correctly initialized |
| gitflow_is_initialized |
| |
| # switch to develop branch if its newly created |
| if [ $created_gitflow_branch -eq 1 ]; then |
| git checkout -q "$develop_branch" |
| fi |
| |
| # finally, ask the user for naming conventions (branch and tag prefixes) |
| if flag force || \ |
| ! git config --get gitflow.prefix.feature >/dev/null 2>&1 || |
| ! git config --get gitflow.prefix.release >/dev/null 2>&1 || |
| ! git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || |
| ! git config --get gitflow.prefix.support >/dev/null 2>&1 || |
| ! git config --get gitflow.prefix.versiontag >/dev/null 2>&1; then |
| echo |
| echo "How to name your supporting branch prefixes?" |
| fi |
| |
| local prefix |
| |
| # Feature branches |
| if ! git config --get gitflow.prefix.feature >/dev/null 2>&1 || flag force; then |
| default_suggestion=$(git config --get gitflow.prefix.feature || echo feature/) |
| printf "Feature branches? [$default_suggestion] " |
| if noflag defaults; then |
| read answer |
| else |
| printf "\n" |
| fi |
| [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} |
| git config gitflow.prefix.feature "$prefix" |
| fi |
| |
| # Release branches |
| if ! git config --get gitflow.prefix.release >/dev/null 2>&1 || flag force; then |
| default_suggestion=$(git config --get gitflow.prefix.release || echo release/) |
| printf "Release branches? [$default_suggestion] " |
| if noflag defaults; then |
| read answer |
| else |
| printf "\n" |
| fi |
| [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} |
| git config gitflow.prefix.release "$prefix" |
| fi |
| |
| |
| # Hotfix branches |
| if ! git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || flag force; then |
| default_suggestion=$(git config --get gitflow.prefix.hotfix || echo hotfix/) |
| printf "Hotfix branches? [$default_suggestion] " |
| if noflag defaults; then |
| read answer |
| else |
| printf "\n" |
| fi |
| [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} |
| git config gitflow.prefix.hotfix "$prefix" |
| fi |
| |
| |
| # Support branches |
| if ! git config --get gitflow.prefix.support >/dev/null 2>&1 || flag force; then |
| default_suggestion=$(git config --get gitflow.prefix.support || echo support/) |
| printf "Support branches? [$default_suggestion] " |
| if noflag defaults; then |
| read answer |
| else |
| printf "\n" |
| fi |
| [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} |
| git config gitflow.prefix.support "$prefix" |
| fi |
| |
| |
| # Version tag prefix |
| if ! git config --get gitflow.prefix.versiontag >/dev/null 2>&1 || flag force; then |
| default_suggestion=$(git config --get gitflow.prefix.versiontag || echo "") |
| printf "Version tag prefix? [$default_suggestion] " |
| if noflag defaults; then |
| read answer |
| else |
| printf "\n" |
| fi |
| [ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion} |
| git config gitflow.prefix.versiontag "$prefix" |
| fi |
| |
| |
| # TODO: what to do with origin? |
| } |
| |
| cmd_help() { |
| usage |
| exit 0 |
| } |