Merge branch 'feature/merge-conflict-support' into develop
diff --git a/git-flow b/git-flow
index 5fbbf8c..5be05f4 100755
--- a/git-flow
+++ b/git-flow
@@ -18,6 +18,7 @@
set -x
fi
+export GIT_DIR=$(git rev-parse --git-dir)
export GITFLOW_DIR=$(dirname "$0")
export MASTER_BRANCH=$(git config --get gitflow.branch.master || echo master)
export DEVELOP_BRANCH=$(git config --get gitflow.branch.develop || echo develop)
@@ -83,11 +84,23 @@
cmd_$SUBACTION "$@"
}
-gitflow_require_clean_working_tree() {
+gitflow_test_clean_working_tree() {
if ! git diff --no-ext-diff --ignore-submodules --quiet --exit-code; then
+ return 1
+ elif ! git diff-index --cached --quiet --ignore-submodules HEAD --; then
+ return 2
+ else
+ return 0
+ fi
+}
+
+gitflow_require_clean_working_tree() {
+ gitflow_test_clean_working_tree
+ result=$?
+ if [ $result -eq 1 ]; then
die "Working tree contains unstaged changes. Aborting ..."
fi
- if ! git diff-index --cached --quiet --ignore-submodules HEAD --; then
+ if [ $result -eq 2 ]; then
die "Index contains uncommited changes. Aborting ..."
fi
}
@@ -162,4 +175,16 @@
fi
}
+#
+# gitflow_is_branch_merged_into()
+#
+# Checks whether branch $1 is succesfully merged into $2
+#
+gitflow_is_branch_merged_into() {
+ local SUBJECT=$1
+ local BASE=$2
+ ALL_MERGES=$(git branch --contains $SUBJECT | sed 's/^[* ] //')
+ has $BASE $ALL_MERGES
+}
+
main "$@"
diff --git a/git-flow-feature b/git-flow-feature
index b9f18b7..482b298 100644
--- a/git-flow-feature
+++ b/git-flow-feature
@@ -102,9 +102,51 @@
parse_args "$@"
# sanity checks
- gitflow_require_clean_working_tree
gitflow_require_branch $BRANCH
+ # detect if we're restoring from a merge conflict
+ if [ -f "$GIT_DIR/.gitflow/MERGE_BASE" ]; then
+ #
+ # TODO: detect that we're working on the correct branch here!
+ # The user need not necessarily have given the same $NAME twice here
+ # (although he/she should).
+ #
+
+ # TODO: gitflow_test_clean_working_tree() should provide an alternative
+ # exit code for "unmerged changes in working tree", which we should
+ # actually be testing for here
+ if gitflow_test_clean_working_tree; then
+ FINISH_BASE="$(cat "$GIT_DIR/.gitflow/MERGE_BASE")"
+
+ # Since the working tree is now clean, either the user did a
+ # succesfull merge manually, or the merge was cancelled.
+ # We detect this using gitflow_is_branch_merged_into()
+ if gitflow_is_branch_merged_into $BRANCH $FINISH_BASE; then
+ rm -f "$GIT_DIR/.gitflow/MERGE_BASE"
+ helper_finish_cleanup
+ exit 0
+ else
+ # If the user cancelled the merge and decided to wait until later,
+ # that's fine. But we have to acknowledge this by removing the
+ # MERGE_BASE file and continuing normal execution of the finish
+ rm -f "$GIT_DIR/.gitflow/MERGE_BASE"
+ fi
+ else
+ echo
+ echo "Merge conflicts not resolved yet, use:"
+ echo " git mergetool"
+ echo " git commit"
+ echo
+ echo "You can then complete the finish by running it again:"
+ echo " git flow feature finish $NAME"
+ echo
+ exit 1
+ fi
+ fi
+
+ # sanity checks
+ gitflow_require_clean_working_tree
+
# update local repo with remote changes first, if asked
if [ $FLAG_FETCH -eq 1 ]; then
git fetch -q $ORIGIN $BRANCH
@@ -125,8 +167,32 @@
git merge --no-ff $BRANCH
fi
+ if [ $? -ne 0 ]; then
+ # oops.. we have a merge conflict!
+ # write the given $BASE to a temporary file (we need it later)
+ mkdir -p "$GIT_DIR/.gitflow"
+ echo "$BASE" > "$GIT_DIR/.gitflow/MERGE_BASE"
+ echo
+ echo "There were merge conflicts. To resolve the merge conflict manually, use:"
+ echo " git mergetool"
+ echo " git commit"
+ echo
+ echo "You can then complete the finish by running it again:"
+ echo " git flow feature finish $NAME"
+ echo
+ exit 1
+ fi
+
+ # when no merge conflict is detected, just clean up the feature branch
+ helper_finish_cleanup
+}
+
+helper_finish_cleanup() {
+ # sanity checks
+ gitflow_require_branch $BRANCH
+ gitflow_check_clean_working_tree
+
# delete branch
- # TODO: How do we handle merge conflicts here??
git push $ORIGIN :refs/heads/$BRANCH
git branch -d $BRANCH