summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--git-rebase--interactive.sh72
-rw-r--r--t/lib-rebase.sh5
-rwxr-xr-xt/t3404-rebase-interactive.sh39
3 files changed, 116 insertions, 0 deletions
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index c26a200a6c..dcc3401b5a 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -846,6 +846,71 @@ add_exec_commands () {
mv "$1.new" "$1"
}
+# Check if the SHA-1 passed as an argument is a
+# correct one, if not then print $2 in "$todo".badsha
+# $1: the SHA-1 to test
+# $2: the line to display if incorrect SHA-1
+check_commit_sha () {
+ badsha=0
+ if test -z $1
+ then
+ badsha=1
+ else
+ sha1_verif="$(git rev-parse --verify --quiet $1^{commit})"
+ if test -z $sha1_verif
+ then
+ badsha=1
+ fi
+ fi
+
+ if test $badsha -ne 0
+ then
+ warn "Warning: the SHA-1 is missing or isn't" \
+ "a commit in the following line:"
+ warn " - $2"
+ warn
+ fi
+
+ return $badsha
+}
+
+# prints the bad commits and bad commands
+# from the todolist in stdin
+check_bad_cmd_and_sha () {
+ retval=0
+ git stripspace --strip-comments |
+ (
+ while read -r line
+ do
+ IFS=' '
+ set -- $line
+ command=$1
+ sha1=$2
+
+ case $command in
+ ''|noop|x|"exec")
+ # Doesn't expect a SHA-1
+ ;;
+ pick|p|drop|d|reword|r|edit|e|squash|s|fixup|f)
+ if ! check_commit_sha $sha1 "$line"
+ then
+ retval=1
+ fi
+ ;;
+ *)
+ warn "Warning: the command isn't recognized" \
+ "in the following line:"
+ warn " - $line"
+ warn
+ retval=1
+ ;;
+ esac
+ done
+
+ return $retval
+ )
+}
+
# Print the list of the SHA-1 of the commits
# from stdin to stdout
todo_list_to_sha_list () {
@@ -887,6 +952,8 @@ get_missing_commit_check_level () {
# Check if the user dropped some commits by mistake
# Behaviour determined by rebase.missingCommitsCheck.
+# Check if there is an unrecognized command or a
+# bad SHA-1 in a command.
check_todo_list () {
raise_error=f
@@ -935,6 +1002,11 @@ check_todo_list () {
;;
esac
+ if ! check_bad_cmd_and_sha <"$todo"
+ then
+ raise_error=t
+ fi
+
if test $raise_error = t
then
# Checkout before the first commit of the
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index fdbc9007d0..9a96e1566d 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -54,6 +54,11 @@ set_fake_editor () {
echo '# comment' >> "$1";;
">")
echo >> "$1";;
+ bad)
+ action="badcmd";;
+ fakesha)
+ echo "$action XXXXXXX False commit" >> "$1"
+ action=pick;;
*)
sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
action=pick;;
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index cfa741018d..ebdab4b95d 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1186,4 +1186,43 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '
test B = $(git cat-file commit HEAD^ | sed -ne \$p)
'
+cat >expect <<EOF
+Warning: the command isn't recognized in the following line:
+ - badcmd $(git rev-list --oneline -1 master~1)
+
+You can fix this with 'git rebase --edit-todo'.
+Or you can abort the rebase with 'git rebase --abort'.
+EOF
+
+test_expect_success 'static check of bad command' '
+ rebase_setup_and_clean bad-cmd &&
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \
+ git rebase -i --root 2>actual &&
+ test_cmp expect actual &&
+ FAKE_LINES="1 2 3 drop 4 5" git rebase --edit-todo &&
+ git rebase --continue &&
+ test E = $(git cat-file commit HEAD | sed -ne \$p) &&
+ test C = $(git cat-file commit HEAD^ | sed -ne \$p)
+'
+
+cat >expect <<EOF
+Warning: the SHA-1 is missing or isn't a commit in the following line:
+ - edit XXXXXXX False commit
+
+You can fix this with 'git rebase --edit-todo'.
+Or you can abort the rebase with 'git rebase --abort'.
+EOF
+
+test_expect_success 'static check of bad SHA-1' '
+ rebase_setup_and_clean bad-sha &&
+ set_fake_editor &&
+ test_must_fail env FAKE_LINES="1 2 edit fakesha 3 4 5 #" \
+ git rebase -i --root 2>actual &&
+ test_cmp expect actual &&
+ FAKE_LINES="1 2 4 5 6" git rebase --edit-todo &&
+ git rebase --continue &&
+ test E = $(git cat-file commit HEAD | sed -ne \$p)
+'
+
test_done