From: Galan Rémi Date: Wed, 10 Jun 2015 10:10:35 GMT Subject: [PATCH/RFCv5 3/3] git rebase -i: add static check for commands and SHA-1 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 --- 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 <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 <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