Commit b96228443755dfeee83c33a9366be74a0323f1ad

Stefan Sperling 2019-08-03T21:49:22

ensure that 'got histedit' refuses to run while shanges are staged

diff --git a/lib/worktree.c b/lib/worktree.c
index 86ead4f..c62f844 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -3701,7 +3701,7 @@ check_rebase_ok(void *arg, struct got_fileindex_entry *ie)
 	    == -1)
 		return got_error_from_errno("asprintf");
 
-	/* Reject rebase of a work tree with modified or conflicted files. */
+	/* Reject rebase of a work tree with modified or staged files. */
 	err = get_file_status(&status, &sb, ie, ondisk_path, a->repo);
 	free(ondisk_path);
 	if (err)
@@ -3709,6 +3709,8 @@ check_rebase_ok(void *arg, struct got_fileindex_entry *ie)
 
 	if (status != GOT_STATUS_NO_CHANGE)
 		return got_error(GOT_ERR_MODIFIED);
+	if (get_staged_status(ie) != GOT_STATUS_NO_CHANGE)
+		return got_error_path(ie->path, GOT_ERR_FILE_STAGED);
 
 	return NULL;
 }
diff --git a/regress/cmdline/stage.sh b/regress/cmdline/stage.sh
index 26db4ab..e433ff7 100755
--- a/regress/cmdline/stage.sh
+++ b/regress/cmdline/stage.sh
@@ -738,6 +738,62 @@ function test_stage_diff {
 
 }
 
+function test_stage_histedit {
+	local testroot=`test_init stage_histedit`
+	local orig_commit=`git_show_head $testroot/repo`
+
+	got checkout -c $orig_commit $testroot/repo $testroot/wt > /dev/null
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo "modified file" > $testroot/wt/alpha
+	(cd $testroot/wt && got stage alpha > /dev/null)
+
+	echo "modified alpha on master" > $testroot/repo/alpha
+	(cd $testroot/repo && git rm -q beta)
+	echo "new file on master" > $testroot/repo/epsilon/new
+	(cd $testroot/repo && git add epsilon/new)
+	git_commit $testroot/repo -m "committing changes"
+	local old_commit1=`git_show_head $testroot/repo`
+
+	echo "modified zeta on master" > $testroot/repo/epsilon/zeta
+	git_commit $testroot/repo -m "committing to zeta on master"
+	local old_commit2=`git_show_head $testroot/repo`
+
+	echo "pick $old_commit1" > $testroot/histedit-script
+	echo "pick $old_commit2" >> $testroot/histedit-script
+
+	(cd $testroot/wt && got histedit -F $testroot/histedit-script \
+		> $testroot/stdout 2> $testroot/stderr)
+	ret="$?"
+	if [ "$ret" == "0" ]; then
+		echo "got histedit command succeeded unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	echo -n > $testroot/stdout.expected
+	echo "got: alpha: file is staged" > $testroot/stderr.expected
+
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
+	test_done "$testroot" "$ret"
+
+}
+
 run_test test_stage_basic
 run_test test_stage_conflict
 run_test test_stage_out_of_date
@@ -747,3 +803,4 @@ run_test test_stage_add_already_staged_file
 run_test test_stage_rm_already_staged_file
 run_test test_stage_revert
 run_test test_stage_diff
+run_test test_stage_histedit