diff options
author | Matthieu Moy <Matthieu.Moy@imag.fr> | 2010-08-10 17:17:51 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2010-08-11 10:21:34 -0700 |
commit | cd035b1cef39811fd3116aa07d99395960ec947a (patch) | |
tree | 6f7a28433e7ac08f97333912a4ef74857d627a48 /git-rebase--interactive.sh | |
parent | 64fdc08dac6694d1e754580e7acb82dfa4988bb9 (diff) | |
download | git-cd035b1cef39811fd3116aa07d99395960ec947a.tar.gz |
rebase -i: add exec command to launch a shell command
The typical usage pattern would be to run a test (or simply a compilation
command) at given points in history.
The shell command is ran (from the worktree root), and the rebase is
stopped when the command fails, to give the user an opportunity to fix
the problem before continuing with "git rebase --continue".
This needs a little rework of skip_unnecessary_picks, which wasn't robust
enough to deal with lines like
exec >"file name with many spaces"
in the todolist. The new version extracts command, sha1 and rest from
each line, but outputs the line itself verbatim to avoid changing the
whitespace layout.
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'git-rebase--interactive.sh')
-rwxr-xr-x | git-rebase--interactive.sh | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 31e68603f4..6c8ff0c46a 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -537,6 +537,34 @@ do_next () { esac record_in_rewritten $sha1 ;; + x|"exec") + read -r command rest < "$TODO" + mark_action_done + printf 'Executing: %s\n' "$rest" + # "exec" command doesn't take a sha1 in the todo-list. + # => can't just use $sha1 here. + git rev-parse --verify HEAD > "$DOTEST"/stopped-sha + ${SHELL:-@SHELL_PATH@} -c "$rest" # Actual execution + status=$? + if test "$status" -ne 0 + then + warn "Execution failed: $rest" + 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) + then + warn "Commit or stash your changes, and then run" + warn + warn " git rebase --continue" + warn + exit 1 + fi + ;; *) warn "Unknown command: $command $sha1 $rest" if git rev-parse --verify -q "$sha1" >/dev/null @@ -591,10 +619,13 @@ do_rest () { # skip picking commits whose parents are unchanged skip_unnecessary_picks () { fd=3 - while read -r command sha1 rest + while read -r line do + command=$(echo "$line" | sed 's/ */ /' | cut -d ' ' -f 1) + sha1=$(echo "$line" | sed 's/ */ /' | cut -d ' ' -f 2) + rest=$(echo "$line" | sed 's/ */ /' | cut -d ' ' -f 3-) # fd=3 means we skip the command - case "$fd,$command,$(git rev-parse --verify --quiet $sha1^)" in + case "$fd,$command,$(git rev-parse --verify --quiet "$sha1"^)" in 3,pick,"$ONTO"*|3,p,"$ONTO"*) # pick a commit whose parent is current $ONTO -> skip ONTO=$sha1 @@ -606,7 +637,7 @@ skip_unnecessary_picks () { fd=1 ;; esac - echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd + echo "$line" >&$fd done <"$TODO" >"$TODO.new" 3>>"$DONE" && mv -f "$TODO".new "$TODO" && case "$(peek_next_command)" in @@ -957,6 +988,7 @@ first and then run 'git rebase --continue' again." # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message +# x <cmd>, exec <cmd> = Run a shell command <cmd>, and stop if it fails # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. |