diff --git a/AUTHORS b/AUTHORS
index f7d1e6638..aded955fc 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -19,5 +19,6 @@ Authors are (ordered by first commit date):
- Emre Berge Ergenekon
- Eric Holmes
- Vedang Manerikar
+- Myke Hines
Portions derived from other open source works are clearly marked.
diff --git a/README.mdown b/README.mdown
index c7238e6f0..b720b125e 100644
--- a/README.mdown
+++ b/README.mdown
@@ -1,3 +1,34 @@
+> [!IMPORTANT]
+>
+> # ⚠️ git-flow has moved to git-flow-next!
+>
+> **This repository is no longer maintained.** The wonderful team at [Tower](https://www.git-tower.com/) has created [**git-flow-next**](https://git-flow.sh) — a modern, fully customizable evolution of git-flow, built on a generic branch dependency model. It’s fully backward compatible with git-flow, open source, and actively maintained.
+>
+> ### Get started with git-flow-next:
+>
+> - **Website:** https://git-flow.sh
+> - **GitHub:** https://github.com/gittower/git-flow-next
+> - **Evolution Story:** Read about the journey from git-flow → git-flow-avh → git-flow-next in [their blog post](https://git-flow.sh/blog)
+>
+> ### Why git-flow-next?
+>
+> git-flow-next builds upon the foundation laid by the original git-flow, offering:
+>
+> - Full customization of branch names and workflow
+> - Modern implementation with active maintenance
+> - Backward compatibility with existing git-flow workflows
+> - Upcoming features like stacked branches and topic branch syncing
+>
+> ### Thank you ❤️
+>
+> To everyone who has used, contributed to, and supported git-flow over the past 15+ years — thank you! Your feedback, contributions, and adoption made git-flow one of the most widely-used Git workflow tools. Special thanks to Peter van der Does for maintaining git-flow-avh, and to the folks at Tower for carrying the torch forward with git-flow-next.
+
+---
+
+(Below, you’ll find the original documentation for historical reference.)
+
+---
+
git-flow
========
@@ -40,37 +71,6 @@ See the [FAQ](http://github.com/nvie/gitflow/wiki/FAQ) section of the project
Wiki.
-Please help out
----------------
-This project is still under development. Feedback and suggestions are very
-welcome and I encourage you to use the [Issues
-list](http://github.com/nvie/gitflow/issues) on Github to provide that
-feedback.
-
-Feel free to fork this repo and to commit your additions. For a list of all
-contributors, please see the [AUTHORS](AUTHORS) file.
-
-Any questions, tips, or general discussion can be posted to our Google group:
-[http://groups.google.com/group/gitflow-users](http://groups.google.com/group/gitflow-users)
-
-Contributing
-------------
-Fork the repository. Then, run:
-
- git clone --recursive git@github.com:/gitflow.git
- cd gitflow
- git branch master origin/master
- git flow init -d
- git flow feature start
-
-Then, do work and commit your changes. **Hint**: ``export PATH=`pwd`:$PATH``
-from within the gitflow directory makes sure you're using the version of
-gitflow you're currently developing.
-
- git flow feature publish
-
-When done, open a pull request to your feature branch.
-
License terms
-------------
git-flow is published under the liberal terms of the BSD License, see the
@@ -131,18 +131,3 @@ The ``-d`` flag will accept all defaults.
git flow support start
For support branches, the `` arg must be a commit on `master`.
-
-
-Showing your appreciation
-=========================
-A few people already requested it, so now it's here: a Flattr button.
-
-Of course, the best way to show your appreciation for the original
-[blog post](http://nvie.com/git-model) or the git-flow tool itself remains
-contributing to the community. If you'd like to show your appreciation in
-another way, however, consider Flattr'ing me:
-
-[![Flattr this][2]][1]
-
-[1]: http://flattr.com/thing/53771/git-flow
-[2]: http://api.flattr.com/button/button-static-50x60.png
diff --git a/contrib/msysgit-install.cmd b/contrib/msysgit-install.cmd
index 5f005bfa7..994235c79 100644
--- a/contrib/msysgit-install.cmd
+++ b/contrib/msysgit-install.cmd
@@ -63,6 +63,7 @@ goto :End
:ChkGetopt
:: %1 is getopt.exe
if exist "%GIT_HOME%\bin\%1" goto :EOF
+if exist "%USERPROFILE%\bin\%1" goto :EOF
if exist "%~f$PATH:1" goto :EOF
echo %GIT_HOME%\bin\%1 not found.>&2
echo You have to install this file manually. See the GitFlow README.
diff --git a/git-flow b/git-flow
index 93e9f0f73..fd16d5168 100755
--- a/git-flow
+++ b/git-flow
@@ -80,6 +80,11 @@ main() {
# use the shFlags project to parse the command line arguments
. "$GITFLOW_DIR/gitflow-shFlags"
FLAGS_PARENT="git flow"
+
+ # allow user to request git action logging
+ DEFINE_boolean show_commands false 'show actions taken (git commands)' g
+
+ # do actual parsing
FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}"
@@ -109,7 +114,10 @@ main() {
fi
# run the specified action
- cmd_$SUBACTION "$@"
+ if [ $SUBACTION != "help" ] && [ $SUBCOMMAND != "init" ] ; then
+ init
+ fi
+ cmd_$SUBACTION "$@"
}
main "$@"
diff --git a/git-flow-feature b/git-flow-feature
index e97d67825..55198ad82 100644
--- a/git-flow-feature
+++ b/git-flow-feature
@@ -36,15 +36,17 @@
# policies, either expressed or implied, of Vincent Driessen.
#
-require_git_repo
-require_gitflow_initialized
-gitflow_load_settings
-PREFIX=$(git config --get gitflow.prefix.feature)
+init() {
+ require_git_repo
+ require_gitflow_initialized
+ gitflow_load_settings
+ PREFIX=$(git config --get gitflow.prefix.feature)
+}
usage() {
echo "usage: git flow feature [list] [-v]"
echo " git flow feature start [-F] []"
- echo " git flow feature finish [-rFkD] []"
+ echo " git flow feature finish [-rFkDS] []"
echo " git flow feature publish "
echo " git flow feature track "
echo " git flow feature diff []"
@@ -202,7 +204,7 @@ cmd_start() {
# update the local repo with remote changes, if asked
if flag fetch; then
- git fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
+ git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
fi
# if the origin branch counterpart exists, assert that the local branch
@@ -212,7 +214,7 @@ cmd_start() {
fi
# create branch
- if ! git checkout -b "$BRANCH" "$BASE"; then
+ if ! git_do checkout -b "$BRANCH" "$BASE"; then
die "Could not create feature branch '$BRANCH'"
fi
@@ -232,6 +234,7 @@ cmd_finish() {
DEFINE_boolean rebase false "rebase instead of merge" r
DEFINE_boolean keep false "keep branch after performing finish" k
DEFINE_boolean force_delete false "force delete feature branch after finish" D
+ DEFINE_boolean squash false "squash feature during merge" S
parse_args "$@"
expand_nameprefix_arg_or_current
@@ -284,8 +287,8 @@ cmd_finish() {
# update local repo with remote changes first, if asked
if has "$ORIGIN/$BRANCH" $(git_remote_branches); then
if flag fetch; then
- git fetch -q "$ORIGIN" "$BRANCH"
- git fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
+ git_do fetch -q "$ORIGIN" "$BRANCH"
+ git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
fi
fi
@@ -308,11 +311,17 @@ cmd_finish() {
fi
# merge into BASE
- git checkout "$DEVELOP_BRANCH"
+ git_do checkout "$DEVELOP_BRANCH"
if [ "$(git rev-list -n2 "$DEVELOP_BRANCH..$BRANCH" | wc -l)" -eq 1 ]; then
- git merge --ff "$BRANCH"
+ git_do merge --ff "$BRANCH"
else
- git merge --no-ff "$BRANCH"
+ if noflag squash; then
+ git_do merge --no-ff "$BRANCH"
+ else
+ git_do merge --squash "$BRANCH"
+ git_do commit
+ git_do merge "$BRANCH"
+ fi
fi
if [ $? -ne 0 ]; then
@@ -342,15 +351,15 @@ helper_finish_cleanup() {
# delete branch
if flag fetch; then
- git push "$ORIGIN" ":refs/heads/$BRANCH"
+ git_do push "$ORIGIN" ":refs/heads/$BRANCH"
fi
if noflag keep; then
if flag force_delete; then
- git branch -D "$BRANCH"
+ git_do branch -D "$BRANCH"
else
- git branch -d "$BRANCH"
+ git_do branch -d "$BRANCH"
fi
fi
@@ -374,17 +383,17 @@ cmd_publish() {
# sanity checks
require_clean_working_tree
require_branch "$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do fetch -q "$ORIGIN"
require_branch_absent "$ORIGIN/$BRANCH"
# create remote branch
- git push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
+ git_do fetch -q "$ORIGIN"
# configure remote tracking
- git config "branch.$BRANCH.remote" "$ORIGIN"
- git config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
- git checkout "$BRANCH"
+ git_do config "branch.$BRANCH.remote" "$ORIGIN"
+ git_do config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
+ git_do checkout "$BRANCH"
echo
echo "Summary of actions:"
@@ -401,11 +410,11 @@ cmd_track() {
# sanity checks
require_clean_working_tree
require_branch_absent "$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do fetch -q "$ORIGIN"
require_branch "$ORIGIN/$BRANCH"
# create tracking branch
- git checkout -b "$BRANCH" "$ORIGIN/$BRANCH"
+ git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH"
echo
echo "Summary of actions:"
@@ -436,7 +445,7 @@ cmd_checkout() {
if [ "$NAME" != "" ]; then
expand_nameprefix_arg
- git checkout "$BRANCH"
+ git_do checkout "$BRANCH"
else
die "Name a feature branch explicitly."
fi
@@ -455,12 +464,12 @@ cmd_rebase() {
require_clean_working_tree
require_branch "$BRANCH"
- git checkout -q "$BRANCH"
+ git_do checkout -q "$BRANCH"
local OPTS=
if flag interactive; then
OPTS="$OPTS -i"
fi
- git rebase $OPTS "$DEVELOP_BRANCH"
+ git_do rebase $OPTS "$DEVELOP_BRANCH"
}
avoid_accidental_cross_branch_action() {
@@ -502,20 +511,20 @@ cmd_pull() {
# we already have a local branch called like this, so simply pull the
# remote changes in
if flag rebase; then
- if ! git pull --rebase -q "$REMOTE" "$BRANCH"; then
+ if ! git_do pull --rebase -q "$REMOTE" "$BRANCH"; then
warn "Pull was aborted. There might be conflicts during rebase or '$REMOTE' might be inaccessible."
exit 1
fi
else
- it pull -q "$REMOTE" "$BRANCH" || die "Failed to pull from remote '$REMOTE'."
+ git_do pull -q "$REMOTE" "$BRANCH" || die "Failed to pull from remote '$REMOTE'."
fi
echo "Pulled $REMOTE's changes into $BRANCH."
else
# setup the local branch clone for the first time
- git fetch -q "$REMOTE" "$BRANCH" || die "Fetch failed." # stores in FETCH_HEAD
- git branch --no-track "$BRANCH" FETCH_HEAD || die "Branch failed."
- git checkout -q "$BRANCH" || die "Checking out new local branch failed."
+ git_do fetch -q "$REMOTE" "$BRANCH" || die "Fetch failed." # stores in FETCH_HEAD
+ git_do branch --no-track "$BRANCH" FETCH_HEAD || die "Branch failed."
+ git_do checkout -q "$BRANCH" || die "Checking out new local branch failed."
echo "Created local branch $BRANCH based on $REMOTE's $BRANCH."
fi
}
diff --git a/git-flow-hotfix b/git-flow-hotfix
index b355f3019..ba485f6fe 100644
--- a/git-flow-hotfix
+++ b/git-flow-hotfix
@@ -36,17 +36,20 @@
# policies, either expressed or implied, of Vincent Driessen.
#
-require_git_repo
-require_gitflow_initialized
-gitflow_load_settings
-VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`")
-PREFIX=$(git config --get gitflow.prefix.hotfix)
+init() {
+ require_git_repo
+ require_gitflow_initialized
+ gitflow_load_settings
+ VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`")
+ PREFIX=$(git config --get gitflow.prefix.hotfix)
+}
usage() {
echo "usage: git flow hotfix [list] [-v]"
echo " git flow hotfix start [-F] []"
echo " git flow hotfix finish [-Fsumpk] "
echo " git flow hotfix publish "
+ echo " git flow hotfix track "
}
cmd_default() {
@@ -166,14 +169,14 @@ cmd_start() {
require_branch_absent "$BRANCH"
require_tag_absent "$VERSION_PREFIX$VERSION"
if flag fetch; then
- git fetch -q "$ORIGIN" "$MASTER_BRANCH"
+ git_do fetch -q "$ORIGIN" "$MASTER_BRANCH"
fi
if has "$ORIGIN/$MASTER_BRANCH" $(git_remote_branches); then
require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
fi
# create branch
- git checkout -b "$BRANCH" "$BASE"
+ git_do checkout -b "$BRANCH" "$BASE"
echo
echo "Summary of actions:"
@@ -196,17 +199,17 @@ cmd_publish() {
# sanity checks
require_clean_working_tree
require_branch "$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do fetch -q "$ORIGIN"
require_branch_absent "$ORIGIN/$BRANCH"
# create remote branch
- git push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
+ git_do fetch -q "$ORIGIN"
# configure remote tracking
git config "branch.$BRANCH.remote" "$ORIGIN"
git config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
- git checkout "$BRANCH"
+ git_do checkout "$BRANCH"
echo
echo "Summary of actions:"
@@ -216,11 +219,32 @@ cmd_publish() {
echo
}
+cmd_track() {
+ parse_args "$@"
+ require_version_arg
+
+ # sanity checks
+ require_clean_working_tree
+ require_branch_absent "$BRANCH"
+ git_do fetch -q "$ORIGIN"
+ require_branch "$ORIGIN/$BRANCH"
+
+ # create tracking branch
+ git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH"
+
+ echo
+ echo "Summary of actions:"
+ echo "- A new remote tracking branch '$BRANCH' was created"
+ echo "- You are now on branch '$BRANCH'"
+ echo
+}
+
cmd_finish() {
DEFINE_boolean fetch false "fetch from $ORIGIN before performing finish" F
DEFINE_boolean sign false "sign the release tag cryptographically" s
DEFINE_string signingkey "" "use the given GPG-key for the digital signature (implies -s)" u
DEFINE_string message "" "use the given tag message" m
+ DEFINE_string messagefile "" "use the contents of the given file as tag message" f
DEFINE_boolean push false "push to $ORIGIN after performing finish" p
DEFINE_boolean keep false "keep branch after performing finish" k
DEFINE_boolean notag false "don't tag this release" n
@@ -236,9 +260,9 @@ cmd_finish() {
require_branch "$BRANCH"
require_clean_working_tree
if flag fetch; then
- git fetch -q "$ORIGIN" "$MASTER_BRANCH" || \
+ git_do fetch -q "$ORIGIN" "$MASTER_BRANCH" || \
die "Could not fetch $MASTER_BRANCH from $ORIGIN."
- git fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \
+ git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \
die "Could not fetch $DEVELOP_BRANCH from $ORIGIN."
fi
if has "$ORIGIN/$MASTER_BRANCH" $(git_remote_branches); then
@@ -252,9 +276,9 @@ cmd_finish() {
# in case a previous attempt to finish this release branch has failed,
# but the merge into master was successful, we skip it now
if ! git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then
- git checkout "$MASTER_BRANCH" || \
+ git_do checkout "$MASTER_BRANCH" || \
die "Could not check out $MASTER_BRANCH."
- git merge --no-ff "$BRANCH" || \
+ git_do merge --no-ff "$BRANCH" || \
die "There were merge conflicts."
# TODO: What do we do now?
fi
@@ -269,7 +293,8 @@ cmd_finish() {
flag sign && opts="$opts -s"
[ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'"
[ "$FLAGS_message" != "" ] && opts="$opts -m '$FLAGS_message'"
- eval git tag $opts "$VERSION_PREFIX$VERSION" || \
+ [ "$FLAGS_messagefile" != "" ] && opts="$opts -F '$FLAGS_messagefile'"
+ eval git_do tag $opts "$VERSION_PREFIX$VERSION" "$BRANCH" || \
die "Tagging failed. Please run finish again to retry."
fi
fi
@@ -278,28 +303,28 @@ cmd_finish() {
# in case a previous attempt to finish this release branch has failed,
# but the merge into develop was successful, we skip it now
if ! git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then
- git checkout "$DEVELOP_BRANCH" || \
+ git_do checkout "$DEVELOP_BRANCH" || \
die "Could not check out $DEVELOP_BRANCH."
# TODO: Actually, accounting for 'git describe' pays, so we should
# ideally git merge --no-ff $tagname here, instead!
- git merge --no-ff "$BRANCH" || \
+ git_do merge --no-ff "$BRANCH" || \
die "There were merge conflicts."
# TODO: What do we do now?
fi
# delete branch
if noflag keep; then
- git branch -d "$BRANCH"
+ git_do branch -d "$BRANCH"
fi
if flag push; then
- git push "$ORIGIN" "$DEVELOP_BRANCH" || \
+ git_do push "$ORIGIN" "$DEVELOP_BRANCH" || \
die "Could not push to $DEVELOP_BRANCH from $ORIGIN."
- git push "$ORIGIN" "$MASTER_BRANCH" || \
+ git_do push "$ORIGIN" "$MASTER_BRANCH" || \
die "Could not push to $MASTER_BRANCH from $ORIGIN."
if noflag notag; then
- git push --tags "$ORIGIN" || \
+ git_do push --tags "$ORIGIN" || \
die "Could not push tags to $ORIGIN."
fi
fi
diff --git a/git-flow-init b/git-flow-init
index 4afa1c25e..5b4e7e807 100644
--- a/git-flow-init
+++ b/git-flow-init
@@ -53,7 +53,7 @@ cmd_default() {
parse_args "$@"
if ! git rev-parse --git-dir >/dev/null 2>&1; then
- git init
+ git_do init
else
# assure that we are not working in a repo with local changes
git_repo_is_headless || require_clean_working_tree
@@ -121,14 +121,14 @@ cmd_default() {
# name exists, checkout that branch and use it for master
if ! git_local_branch_exists "$master_branch" && \
git_remote_branch_exists "origin/$master_branch"; then
- git branch "$master_branch" "origin/$master_branch" >/dev/null 2>&1
+ git_do branch "$master_branch" "origin/$master_branch" >/dev/null 2>&1
elif ! git_local_branch_exists "$master_branch"; then
die "Local branch '$master_branch' does not exist."
fi
fi
# store the name of the master branch
- git config gitflow.branch.master "$master_branch"
+ git_do config gitflow.branch.master "$master_branch"
fi
# add a develop branch if no such branch exists yet
@@ -153,11 +153,17 @@ cmd_default() {
default_suggestion=
for guess in $(git config --get gitflow.branch.develop) \
'develop' 'int' 'integration' 'master'; do
- if git_local_branch_exists "$guess"; then
+ if git_local_branch_exists "$guess" && [ "$guess" != "$master_branch" ]; then
default_suggestion="$guess"
break
fi
done
+
+ if [ -z $default_suggestion ]; then
+ should_check_existence=NO
+ default_suggestion=$(git config --get gitflow.branch.develop || echo develop)
+ fi
+
fi
printf "Branch name for \"next release\" development: [$default_suggestion] "
@@ -179,7 +185,7 @@ cmd_default() {
fi
# store the name of the develop branch
- git config gitflow.branch.develop "$develop_branch"
+ git_do config gitflow.branch.develop "$develop_branch"
fi
# Creation of HEAD
@@ -188,8 +194,8 @@ cmd_default() {
# 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"
+ git_do symbolic-ref HEAD "refs/heads/$master_branch"
+ git_do commit --allow-empty --quiet -m "Initial commit"
created_gitflow_branch=1
fi
@@ -207,9 +213,9 @@ cmd_default() {
# the develop branch now in that case (we base it on master, of course)
if ! git_local_branch_exists "$develop_branch"; then
if git_remote_branch_exists "origin/$develop_branch"; then
- git branch "$develop_branch" "origin/$develop_branch" >/dev/null 2>&1
+ git_do branch "$develop_branch" "origin/$develop_branch" >/dev/null 2>&1
else
- git branch --no-track "$develop_branch" "$master_branch"
+ git_do branch --no-track "$develop_branch" "$master_branch"
fi
created_gitflow_branch=1
fi
@@ -219,7 +225,7 @@ cmd_default() {
# switch to develop branch if its newly created
if [ $created_gitflow_branch -eq 1 ]; then
- git checkout -q "$develop_branch"
+ git_do checkout -q "$develop_branch"
fi
# finally, ask the user for naming conventions (branch and tag prefixes)
@@ -245,7 +251,7 @@ cmd_default() {
printf "\n"
fi
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
- git config gitflow.prefix.feature "$prefix"
+ git_do config gitflow.prefix.feature "$prefix"
fi
# Release branches
@@ -258,7 +264,7 @@ cmd_default() {
printf "\n"
fi
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
- git config gitflow.prefix.release "$prefix"
+ git_do config gitflow.prefix.release "$prefix"
fi
@@ -272,7 +278,7 @@ cmd_default() {
printf "\n"
fi
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
- git config gitflow.prefix.hotfix "$prefix"
+ git_do config gitflow.prefix.hotfix "$prefix"
fi
@@ -286,7 +292,7 @@ cmd_default() {
printf "\n"
fi
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
- git config gitflow.prefix.support "$prefix"
+ git_do config gitflow.prefix.support "$prefix"
fi
@@ -300,7 +306,7 @@ cmd_default() {
printf "\n"
fi
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
- git config gitflow.prefix.versiontag "$prefix"
+ git_do config gitflow.prefix.versiontag "$prefix"
fi
diff --git a/git-flow-release b/git-flow-release
index bb39d5276..cb95bd486 100644
--- a/git-flow-release
+++ b/git-flow-release
@@ -36,16 +36,18 @@
# policies, either expressed or implied, of Vincent Driessen.
#
-require_git_repo
-require_gitflow_initialized
-gitflow_load_settings
-VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`")
-PREFIX=$(git config --get gitflow.prefix.release)
+init() {
+ require_git_repo
+ require_gitflow_initialized
+ gitflow_load_settings
+ VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`")
+ PREFIX=$(git config --get gitflow.prefix.release)
+}
usage() {
echo "usage: git flow release [list] [-v]"
echo " git flow release start [-F] []"
- echo " git flow release finish [-Fsumpk] "
+ echo " git flow release finish [-FsumpkS] "
echo " git flow release publish "
echo " git flow release track "
}
@@ -134,7 +136,7 @@ require_version_arg() {
}
require_base_is_on_develop() {
- if ! git branch --no-color --contains "$BASE" 2>/dev/null \
+ if ! git_do branch --no-color --contains "$BASE" 2>/dev/null \
| sed 's/[* ] //g' \
| grep -q "^$DEVELOP_BRANCH\$"; then
die "fatal: Given base '$BASE' is not a valid commit on '$DEVELOP_BRANCH'."
@@ -162,14 +164,14 @@ cmd_start() {
require_branch_absent "$BRANCH"
require_tag_absent "$VERSION_PREFIX$VERSION"
if flag fetch; then
- git fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
+ git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH"
fi
if has "$ORIGIN/$DEVELOP_BRANCH" $(git_remote_branches); then
require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
fi
# create branch
- git checkout -b "$BRANCH" "$BASE"
+ git_do checkout -b "$BRANCH" "$BASE"
echo
echo "Summary of actions:"
@@ -190,9 +192,11 @@ cmd_finish() {
DEFINE_boolean sign false "sign the release tag cryptographically" s
DEFINE_string signingkey "" "use the given GPG-key for the digital signature (implies -s)" u
DEFINE_string message "" "use the given tag message" m
+ DEFINE_string messagefile "" "use the contents of the given file as a tag message" f
DEFINE_boolean push false "push to $ORIGIN after performing finish" p
DEFINE_boolean keep false "keep branch after performing finish" k
DEFINE_boolean notag false "don't tag this release" n
+ DEFINE_boolean squash false "squash release during merge" S
parse_args "$@"
require_version_arg
@@ -206,9 +210,9 @@ cmd_finish() {
require_branch "$BRANCH"
require_clean_working_tree
if flag fetch; then
- git fetch -q "$ORIGIN" "$MASTER_BRANCH" || \
+ git_do fetch -q "$ORIGIN" "$MASTER_BRANCH" || \
die "Could not fetch $MASTER_BRANCH from $ORIGIN."
- git fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \
+ git_do fetch -q "$ORIGIN" "$DEVELOP_BRANCH" || \
die "Could not fetch $DEVELOP_BRANCH from $ORIGIN."
fi
if has "$ORIGIN/$MASTER_BRANCH" $(git_remote_branches); then
@@ -222,11 +226,17 @@ cmd_finish() {
# in case a previous attempt to finish this release branch has failed,
# but the merge into master was successful, we skip it now
if ! git_is_branch_merged_into "$BRANCH" "$MASTER_BRANCH"; then
- git checkout "$MASTER_BRANCH" || \
+ git_do checkout "$MASTER_BRANCH" || \
die "Could not check out $MASTER_BRANCH."
- git merge --no-ff "$BRANCH" || \
- die "There were merge conflicts."
- # TODO: What do we do now?
+ if noflag squash; then
+ git_do merge --no-ff "$BRANCH" || \
+ die "There were merge conflicts."
+ # TODO: What do we do now?
+ else
+ git_do merge --squash "$BRANCH" || \
+ die "There were merge conflicts."
+ git_do commit
+ fi
fi
if noflag notag; then
@@ -239,7 +249,8 @@ cmd_finish() {
flag sign && opts="$opts -s"
[ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'"
[ "$FLAGS_message" != "" ] && opts="$opts -m '$FLAGS_message'"
- eval git tag $opts "$tagname" || \
+ [ "$FLAGS_messagefile" != "" ] && opts="$opts -F '$FLAGS_messagefile'"
+ eval git_do tag $opts "$tagname" "$BRANCH" || \
die "Tagging failed. Please run finish again to retry."
fi
fi
@@ -248,34 +259,41 @@ cmd_finish() {
# in case a previous attempt to finish this release branch has failed,
# but the merge into develop was successful, we skip it now
if ! git_is_branch_merged_into "$BRANCH" "$DEVELOP_BRANCH"; then
- git checkout "$DEVELOP_BRANCH" || \
+ git_do checkout "$DEVELOP_BRANCH" || \
die "Could not check out $DEVELOP_BRANCH."
# TODO: Actually, accounting for 'git describe' pays, so we should
# ideally git merge --no-ff $tagname here, instead!
- git merge --no-ff "$BRANCH" || \
- die "There were merge conflicts."
- # TODO: What do we do now?
+ if noflag squash; then
+ git_do merge --no-ff "$BRANCH" || \
+ die "There were merge conflicts."
+ # TODO: What do we do now?
+ else
+ git_do merge --squash "$BRANCH" || \
+ die "There were merge conflicts."
+ # TODO: What do we do now?
+ git_do commit
+ fi
fi
# delete branch
if noflag keep; then
if [ "$BRANCH" = "$(git_current_branch)" ]; then
- git checkout "$MASTER_BRANCH"
+ git_do checkout "$MASTER_BRANCH"
fi
- git branch -d "$BRANCH"
+ git_do branch -d "$BRANCH"
fi
if flag push; then
- git push "$ORIGIN" "$DEVELOP_BRANCH" || \
+ git_do push "$ORIGIN" "$DEVELOP_BRANCH" || \
die "Could not push to $DEVELOP_BRANCH from $ORIGIN."
- git push "$ORIGIN" "$MASTER_BRANCH" || \
+ git_do push "$ORIGIN" "$MASTER_BRANCH" || \
die "Could not push to $MASTER_BRANCH from $ORIGIN."
if noflag notag; then
- git push --tags "$ORIGIN" || \
+ git_do push --tags "$ORIGIN" || \
die "Could not push tags to $ORIGIN."
fi
- git push "$ORIGIN" :"$BRANCH" || \
+ git_do push "$ORIGIN" :"$BRANCH" || \
die "Could not delete the remote $BRANCH in $ORIGIN."
fi
@@ -306,17 +324,17 @@ cmd_publish() {
# sanity checks
require_clean_working_tree
require_branch "$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do fetch -q "$ORIGIN"
require_branch_absent "$ORIGIN/$BRANCH"
# create remote branch
- git push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do push "$ORIGIN" "$BRANCH:refs/heads/$BRANCH"
+ git_do fetch -q "$ORIGIN"
# configure remote tracking
- git config "branch.$BRANCH.remote" "$ORIGIN"
- git config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
- git checkout "$BRANCH"
+ git_do config "branch.$BRANCH.remote" "$ORIGIN"
+ git_do config "branch.$BRANCH.merge" "refs/heads/$BRANCH"
+ git_do checkout "$BRANCH"
echo
echo "Summary of actions:"
@@ -333,11 +351,11 @@ cmd_track() {
# sanity checks
require_clean_working_tree
require_branch_absent "$BRANCH"
- git fetch -q "$ORIGIN"
+ git_do fetch -q "$ORIGIN"
require_branch "$ORIGIN/$BRANCH"
# create tracking branch
- git checkout -b "$BRANCH" "$ORIGIN/$BRANCH"
+ git_do checkout -b "$BRANCH" "$ORIGIN/$BRANCH"
echo
echo "Summary of actions:"
diff --git a/git-flow-support b/git-flow-support
index 605694dc9..cdbfc717c 100644
--- a/git-flow-support
+++ b/git-flow-support
@@ -36,11 +36,13 @@
# policies, either expressed or implied, of Vincent Driessen.
#
-require_git_repo
-require_gitflow_initialized
-gitflow_load_settings
-VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`")
-PREFIX=$(git config --get gitflow.prefix.support)
+init() {
+ require_git_repo
+ require_gitflow_initialized
+ gitflow_load_settings
+ VERSION_PREFIX=$(eval "echo `git config --get gitflow.prefix.versiontag`")
+ PREFIX=$(git config --get gitflow.prefix.support)
+}
warn "note: The support subcommand is still very EXPERIMENTAL!"
warn "note: DO NOT use it in a production situation."
@@ -167,12 +169,12 @@ cmd_start() {
# fetch remote changes
if flag fetch; then
- git fetch -q "$ORIGIN" "$BASE"
+ git_do fetch -q "$ORIGIN" "$BASE"
fi
require_branch_absent "$BRANCH"
# create branch
- git checkout -b "$BRANCH" "$BASE"
+ git_do checkout -b "$BRANCH" "$BASE"
echo
echo "Summary of actions:"
diff --git a/gitflow-common b/gitflow-common
index 4834cf102..332740533 100644
--- a/gitflow-common
+++ b/gitflow-common
@@ -70,6 +70,14 @@ noflag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -ne $FLAGS_TRUE ]; }
# Git specific common functionality
#
+git_do() {
+ # equivalent to git, used to indicate actions that make modifications
+ if flag show_commands; then
+ echo "git $@" >&2
+ fi
+ git "$@"
+}
+
git_local_branches() { git branch --no-color | sed 's/^[* ] //'; }
git_remote_branches() { git branch -r --no-color | sed 's/^[* ] //'; }
git_all_branches() { ( git branch --no-color; git branch -r --no-color) | sed 's/^[* ] //'; }