Merge branch 'feature/annotated-signed-tags' into develop
diff --git a/git-flow-hotfix b/git-flow-hotfix
index 7ffa39b..4333e30 100644
--- a/git-flow-hotfix
+++ b/git-flow-hotfix
@@ -113,7 +113,7 @@
}
cmd_start() {
- DEFINE_boolean fetch true "fetch from $ORIGIN before finishing hotfix" F
+ DEFINE_boolean fetch true "fetch from $ORIGIN before performing finish" F
parse_args "$@"
BASE="${2:-$MASTER_BRANCH}"
require_version_arg
@@ -121,11 +121,12 @@
# sanity checks
gitflow_require_clean_working_tree
+ gitflow_require_branch_absent $BRANCH
+ gitflow_require_tag_absent $VERSION_PREFIX$VERSION
if flag fetch; then
git fetch -q $ORIGIN $MASTER_BRANCH
fi
gitflow_require_branches_equal $MASTER_BRANCH $ORIGIN/$MASTER_BRANCH
- gitflow_require_branch_absent $BRANCH
# create branch
git checkout -b $BRANCH $BASE
@@ -145,27 +146,67 @@
}
cmd_finish() {
- DEFINE_boolean fetch true "fetch from $ORIGIN before finishing hotfix" F
+ DEFINE_boolean fetch true "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
parse_args "$@"
require_version_arg
+ # handle flags that imply other flags
+ if [ "$FLAGS_signingkey" != "" ]; then
+ FLAGS_sign=$FLAGS_TRUE
+ fi
+
# sanity checks
+ gitflow_require_branch $BRANCH
gitflow_require_clean_working_tree
if flag fetch; then
- git fetch -q $ORIGIN $MASTER_BRANCH
- git fetch -q $ORIGIN $DEVELOP_BRANCH
+ git fetch -q $ORIGIN $MASTER_BRANCH || \
+ die "Could not fetch $MASTER_BRANCH from $ORIGIN."
+ git fetch -q $ORIGIN $DEVELOP_BRANCH || \
+ die "Could not fetch $DEVELOP_BRANCH from $ORIGIN."
fi
gitflow_require_branches_equal $MASTER_BRANCH $ORIGIN/$MASTER_BRANCH
gitflow_require_branches_equal $DEVELOP_BRANCH $ORIGIN/$DEVELOP_BRANCH
- # merge into master
- git checkout $MASTER_BRANCH
- git merge --no-ff $BRANCH
- git tag $VERSION_PREFIX$VERSION
+ # try to merge into master
+ # in case a previous attempt to finish this release branch has failed,
+ # but the merge into master was successful, we skip it now
+ if ! gitflow_is_branch_merged_into $BRANCH $MASTER_BRANCH; then
+ git 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?
+ fi
- # merge into develop if we fixed a master issue
- git checkout $DEVELOP_BRANCH
- git merge --no-ff $BRANCH
+ # try to tag the release
+ # in case a previous attempt to finish this release branch has failed,
+ # but the tag was set successful, we skip it now
+ typeset tagname=$VERSION_PREFIX$VERSION
+ if ! gitflow_tag_exists $tagname; then
+ typeset opts="-a"
+ flag sign && opts="$opts -s"
+ [ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'"
+ [ "$FLAGS_message" != "" ] && opts="$opts -m '$FLAGS_message'"
+ git tag $opts "$VERSION_PREFIX$VERSION" || \
+ die "Tagging failed. Please run finish again to retry."
+ fi
+
+ # try to merge into develop
+ # in case a previous attempt to finish this release branch has failed,
+ # but the merge into develop was successful, we skip it now
+ if ! gitflow_is_branch_merged_into $BRANCH $DEVELOP_BRANCH; then
+ git 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?
+ fi
# delete branch
git branch -d $BRANCH
diff --git a/git-flow-release b/git-flow-release
index 8fb4061..9750cc8 100644
--- a/git-flow-release
+++ b/git-flow-release
@@ -127,11 +127,12 @@
# sanity checks
gitflow_require_clean_working_tree
+ gitflow_require_branch_absent $BRANCH
+ gitflow_require_tag_absent $VERSION_PREFIX$VERSION
if flag fetch; then
git fetch -q $ORIGIN $DEVELOP_BRANCH
fi
gitflow_require_branches_equal $DEVELOP_BRANCH $ORIGIN/$DEVELOP_BRANCH
- gitflow_require_branch_absent $BRANCH
# create branch
git checkout -b $BRANCH $BASE
@@ -152,26 +153,66 @@
cmd_finish() {
DEFINE_boolean fetch true "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
parse_args "$@"
require_version_arg
+ # handle flags that imply other flags
+ if [ "$FLAGS_signingkey" != "" ]; then
+ FLAGS_sign=$FLAGS_TRUE
+ fi
+
# sanity checks
+ gitflow_require_branch $BRANCH
gitflow_require_clean_working_tree
if flag fetch; then
- git fetch -q $ORIGIN $MASTER_BRANCH
- git fetch -q $ORIGIN $DEVELOP_BRANCH
+ git fetch -q $ORIGIN $MASTER_BRANCH || \
+ die "Could not fetch $MASTER_BRANCH from $ORIGIN."
+ git fetch -q $ORIGIN $DEVELOP_BRANCH || \
+ die "Could not fetch $DEVELOP_BRANCH from $ORIGIN."
fi
gitflow_require_branches_equal $MASTER_BRANCH $ORIGIN/$MASTER_BRANCH
gitflow_require_branches_equal $DEVELOP_BRANCH $ORIGIN/$DEVELOP_BRANCH
- # merge into master
- git checkout $MASTER_BRANCH
- git merge --no-ff $BRANCH
- git tag $VERSION_PREFIX$VERSION
+ # try to merge into master
+ # in case a previous attempt to finish this release branch has failed,
+ # but the merge into master was successful, we skip it now
+ if ! gitflow_is_branch_merged_into $BRANCH $MASTER_BRANCH; then
+ git 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?
+ fi
- # merge into develop
- git checkout $DEVELOP_BRANCH
- git merge --no-ff $BRANCH
+ # try to tag the release
+ # in case a previous attempt to finish this release branch has failed,
+ # but the tag was set successful, we skip it now
+ typeset tagname=$VERSION_PREFIX$VERSION
+ if ! gitflow_tag_exists $tagname; then
+ typeset opts="-a"
+ flag sign && opts="$opts -s"
+ [ "$FLAGS_signingkey" != "" ] && opts="$opts -u '$FLAGS_signingkey'"
+ [ "$FLAGS_message" != "" ] && opts="$opts -m '$FLAGS_message'"
+ git tag $opts "$tagname" || \
+ die "Tagging failed. Please run finish again to retry."
+ fi
+
+ # try to merge into develop
+ # in case a previous attempt to finish this release branch has failed,
+ # but the merge into develop was successful, we skip it now
+ if ! gitflow_is_branch_merged_into $BRANCH $DEVELOP_BRANCH; then
+ git 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?
+ fi
# delete branch
git branch -d $BRANCH
@@ -183,7 +224,7 @@
echo "Summary of actions:"
echo "- Latest objects have been fetched from '$ORIGIN'"
echo "- Release branch has been merged into '$MASTER_BRANCH'"
- echo "- The release was tagged '$VERSION_PREFIX$VERSION'"
+ echo "- The release was tagged '$tagname'"
echo "- Release branch has been back-merged into '$DEVELOP_BRANCH'"
echo "- Release branch '$BRANCH' has been deleted"
echo
diff --git a/gitflow-common b/gitflow-common
index 2fbd8ec..4f2a85a 100644
--- a/gitflow-common
+++ b/gitflow-common
@@ -42,6 +42,7 @@
LOCAL_BRANCHES=$(git branch | sed 's/^[* ] //')
REMOTE_BRANCHES=$(git branch -r | sed 's/^[* ] //')
ALL_BRANCHES="$LOCAL_BRANCHES $REMOTE_BRANCHES"
+ALL_TAGS=$(git tag)
#
# resolve_nameprefix
@@ -141,6 +142,16 @@
fi
}
+gitflow_require_tag_absent() {
+ if has $1 $ALL_TAGS; then
+ die "Tag '$1' already exists. Pick another name."
+ fi
+}
+
+gitflow_tag_exists() {
+ has $1 $ALL_TAGS
+}
+
#
# gitflow_test_branches_equal()
#