From ffaaed88aed2e9b7936a0c5b43c1b198db0dc2ab Mon Sep 17 00:00:00 2001
From: Matthieu Moy <Matthieu.Moy@imag.fr>
Date: Wed, 24 Aug 2011 16:01:48 +0200
Subject: [PATCH 1/2] rebase -i: clean error message for --continue after
 failed exec

After an "exec false" stops the rebase and gives the control back to
the user, if changes are added to the index, "rebase --continue" fails
with this message, which may technically be correct, but does not point
at the real problem:

.../git-rebase--interactive: line 774: .../.git/rebase-merge/author-script: No such file or directory

We could try auto-amending HEAD, but this goes against the logic of
.git/rebase-merge/author-script (see also the testcase 'auto-amend only
edited commits after "edit"' in t3404-rebase-interactive.sh) to
auto-amend something the user hasn't explicitely asked to edit.

Instead of doing anything automatically, detect the situation and give a
clean error message. While we're there, also clarify the error message in
case '. "$author_script"' fails, which now corresponds to really weird
senario where the author script exists but can't be read.

Test-case-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-rebase--interactive.sh    | 18 +++++++++++++++++-
 t/t3404-rebase-interactive.sh | 14 ++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index c6ba7c15510..5c945060983 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -647,8 +647,24 @@ continue)
 	then
 		: Nothing to commit -- skip this
 	else
+		if ! test -f "$author_script"
+		then
+			die "You have staged changes in your working tree. If these changes are meant to be
+squashed into the previous commit, run:
+
+  git commit --amend
+
+If they are meant to go into a new commit, run:
+
+  git commit
+
+In both case, once you're done, continue with:
+
+  git rebase --continue
+"
+		fi
 		. "$author_script" ||
-			die "Cannot find the author identity"
+			die "Error trying to find the author identity to amend commit"
 		current_head=
 		if test -f "$amend"
 		then
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 8538813d1d0..b981572d736 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -527,6 +527,20 @@ test_expect_success 'auto-amend only edited commits after "edit"' '
 	git rebase --abort
 '
 
+test_expect_success 'clean error after failed "exec"' '
+	test_tick &&
+	test_when_finished "git rebase --abort || :" &&
+	(
+		FAKE_LINES="1 exec_false" &&
+		export FAKE_LINES &&
+		test_must_fail git rebase -i HEAD^
+	) &&
+	echo "edited again" > file7 &&
+	git add file7 &&
+	test_must_fail git rebase --continue 2>error &&
+	grep "You have staged changes in your working tree." error
+'
+
 test_expect_success 'rebase a detached HEAD' '
 	grandparent=$(git rev-parse HEAD~2) &&
 	git checkout $(git rev-parse HEAD) &&

From 1686519a0854ec09ee1cdd6db7f570ea4590dfce Mon Sep 17 00:00:00 2001
From: Junio C Hamano <gitster@pobox.com>
Date: Wed, 24 Aug 2011 11:54:50 -0700
Subject: [PATCH 2/2] rebase -i: notice and warn if "exec $cmd" modifies the
 index or the working tree

If "exec $cmd" touched the index or the working tree, and exited with
non-zero status, the code did not check and warn that there now are
uncommitted changes.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-rebase--interactive.sh | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 5c945060983..94f36c254c5 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -472,18 +472,24 @@ do_next () {
 		git rev-parse --verify HEAD > "$state_dir"/stopped-sha
 		${SHELL:-@SHELL_PATH@} -c "$rest" # Actual execution
 		status=$?
+		# Run in subshell because require_clean_work_tree can die.
+		dirty=f
+		(require_clean_work_tree "rebase" 2>/dev/null) || dirty=t
 		if test "$status" -ne 0
 		then
 			warn "Execution failed: $rest"
+			test "$dirty" = f ||
+			warn "and made changes to the index and/or the working tree"
+
 			warn "You can fix the problem, and then run"
 			warn
 			warn "	git rebase --continue"
 			warn
 			exit "$status"
-		fi
-		# Run in subshell because require_clean_work_tree can die.
-		if ! (require_clean_work_tree "rebase")
+		elif test "$dirty" = t
 		then
+			warn "Execution succeeded: $rest"
+			warn "but left changes to the index and/or the working tree"
 			warn "Commit or stash your changes, and then run"
 			warn
 			warn "	git rebase --continue"