git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH/RFCv5 3/3] git rebase -i: add static check for commands and SHA-1

From
Galan Rémi <remi.galan-alfonso@ensimag.grenoble-inp.fr>
Date
Jun 10, 2015, 10:10 UTC
Message-ID
<1433931035-20011-3-git-send-email-remi.galan-alfonso@ensimag.grenoble-inp.fr>
In-Reply-To
<1433931035-20011-1-git-send-email-remi.galan-alfonso@ensimag.grenoble-inp.fr>

Check before the start of the rebasing if the commands exists, and for the commands expecting a SHA-1, check if the SHA-1 is present and corresponds to a commit. In case of error, print the error, stop git rebase and prompt the user to fix with 'git rebase --edit-todo' or to abort.

This allows to avoid doing half of a rebase before finding an error and giving back what's left of the todo list to the user and prompt him to fix when it might be too late for him to do so (he might have to abort and restart the rebase).

Signed-off-by: Galan Rémi <remi.galan-alfonso@ensimag.grenoble-inp.fr>
---
 git-rebase--interactive.sh    | 63 +++++++++++++++++++++++++++++++++++++++++++
 t/lib-rebase.sh               |  5 ++++
 t/t3404-rebase-interactive.sh | 40 +++++++++++++++++++++++++++
 3 files changed, 108 insertions(+)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 68a71d0..226a8a8 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -834,6 +834,47 @@ add_exec_commands () {
 	mv "$1.new" "$1"
 }
 
+# prints the bad commits and bad commands
+# from the todolist in stdin
+check_bad_cmd_and_sha () {
+	git stripspace --strip-comments |
+	while read -r command sha1 rest
+	do
+		case $command in
+		''|noop|x|"exec")
+			;;
+		pick|p|drop|d|reword|r|edit|e|squash|s|fixup|f)
+			if test -z $sha1
+			then
+				echo "$command $rest" >>"$todo".badsha
+			else
+				sha1_verif="$(git rev-parse --verify --quiet $sha1^{commit})"
+				if test -z $sha1_verif
+				then
+					echo "$command $sha1 $rest" \
+						>>"$todo".badsha
+				fi
+			fi
+			;;
+		*)
+			if test -z $sha1
+			then
+				echo "$command" >>"$todo".badcmd
+			else
+				commit="$(git rev-list --oneline -1 --ignore-missing $sha1 2>/dev/null)"
+				if test -z "$commit"
+				then
+					echo "$command $sha1 $rest" \
+						>>"$todo".badcmd
+				else
+					echo "$command $commit" >>"$todo".badcmd
+				fi
+			fi
+			;;
+		esac
+	done
+}
+
 # Print the list of the SHA-1 of the commits
 # from stdin to stdout
 todo_list_to_sha_list () {
@@ -913,6 +954,28 @@ check_todo_list () {
 		;;
 	esac
 
+	check_bad_cmd_and_sha <"$todo"
+
+	if test -s "$todo".badsha
+	then
+		raiseError=t
+
+		warn "Warning: the SHA-1 is missing or isn't" \
+			"a commit in the following line(s):"
+		warn_file "$todo".badsha
+		warn
+	fi
+
+	if test -s "$todo".badcmd
+	then
+		raiseError=t
+
+		warn "Warning: the command isn't recognized" \
+			"in the following line(s):"
+		warn_file "$todo".badcmd
+		warn
+	fi
+
 	if test $raiseError = t
 	then
 		# Checkout before the first commit of the
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index fdbc900..9a96e15 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 a92ae19..d691b1c 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1184,4 +1184,44 @@ 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(s):
+ - 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' '
+	test_rebase_end tmp2 &&
+	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(s):
+ - 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' '
+	test_config rebase.missingCommitsCheck error &&
+	test_rebase_end tmp2 &&
+	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
-- 
2.4.2.496.gdc9319a
Previous: Remi Galan AlfonsoNext: Matthieu Moy
Message 7 of 12 in “git-rebase -i: add command "drop" to remove a commit”
  1. 1/3 git-rebase -i: add command "drop" to remove a commitGalan Rémi, Jun 10, 2015
  2. 2/3 git rebase -i: warn about removed commitsGalan Rémi, Jun 10, 2015
  3. Matthieu MoyJun 10, 2015
  4. Remi Galan AlfonsoJun 10, 2015
  5. Matthieu MoyJun 10, 2015
  6. Remi Galan AlfonsoJun 10, 2015
  7. 3/3 git rebase -i: add static check for commands and SHA-1Galan Rémi, Jun 10, 2015
  8. Matthieu MoyJun 10, 2015
  9. Remi Galan AlfonsoJun 10, 2015
  10. Matthieu MoyJun 10, 2015
  11. Remi Galan AlfonsoJun 13, 2015
  12. Matthieu MoyJun 15, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.