mirror of
https://github.com/git/git
synced 2024-08-27 19:49:21 +00:00
rebase: avoid non-function use of "return" on FreeBSD
Sincea1549e10
,15d4bf2e
and01a1e646
(first appearing in v1.8.4) the git-rebase--*.sh scripts have used a "return" to stop execution of the dot-sourced file and return to the "dot" command that dot-sourced it. The /bin/sh utility on FreeBSD however behaves poorly under some circumstances when such a "return" is executed. In particular, if the "dot" command is contained within a function, then when a "return" is executed by the script it runs (that is not itself inside a function), control will return from the function that contains the "dot" command skipping any statements that might follow the dot command inside that function. Commit99855ddf
(first appearing in v1.8.4.1) addresses this by making the "dot" command the last line in the function. Unfortunately the FreeBSD /bin/sh may also execute some statements in the script run by the "dot" command that appear after the troublesome "return". The fix in99855ddf
does not address this problem. For example, if you have script1.sh with these contents: run_script2() { . "$(dirname -- "$0")/script2.sh" _e=$? echo only this line should show [ $_e -eq 5 ] || echo expected status 5 got $_e return 3 } run_script2 e=$? [ $e -eq 3 ] || { echo expected status 3 got $e; exit 1; } And script2.sh with these contents: if [ 5 -gt 3 ]; then return 5 fi case bad in *) echo always shows esac echo should not get here ! : When running script1.sh (e.g. '/bin/sh script1.sh' or './script1.sh' after making it executable), the expected output from a POSIX shell is simply the single line: only this line should show However, when run using FreeBSD's /bin/sh, the following output appears instead: should not get here expected status 3 got 1 Not only did the lines following the "dot" command in the run_script2 function in script1.sh get skipped, but additional lines in script2.sh following the "return" got executed -- but not all of them (e.g. the "echo always shows" line did not run). These issues can be avoided by not using a top-level "return" in script2.sh. If script2.sh is changed to this: main() { if [ 5 -gt 3 ]; then return 5 fi case bad in *) echo always shows esac echo should not get here ! : } main Then it behaves the same when using FreeBSD's /bin/sh as when using other more POSIX compliant /bin/sh implementations. We fix the git-rebase--*.sh scripts in a similar fashion by moving the top-level code that contains "return" statements into its own function and then calling that as the last line in the script. Signed-off-by: Kyle J. McKay <mackyle@gmail.com> Acked-by: Matthieu Moy <Matthieu.Moy@imag.fr> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
0bc85abb7a
commit
9f50d32b9c
|
@ -4,6 +4,17 @@
|
|||
# Copyright (c) 2010 Junio C Hamano.
|
||||
#
|
||||
|
||||
# The whole contents of this file is run by dot-sourcing it from
|
||||
# inside a shell function. It used to be that "return"s we see
|
||||
# below were not inside any function, and expected to return
|
||||
# to the function that dot-sourced us.
|
||||
#
|
||||
# However, FreeBSD /bin/sh misbehaves on such a construct and
|
||||
# continues to run the statements that follow such a "return".
|
||||
# As a work-around, we introduce an extra layer of a function
|
||||
# here, and immediately call it after defining it.
|
||||
git_rebase__am () {
|
||||
|
||||
case "$action" in
|
||||
continue)
|
||||
git am --resolved --resolvemsg="$resolvemsg" &&
|
||||
|
@ -73,3 +84,7 @@ then
|
|||
fi
|
||||
|
||||
move_to_original_branch
|
||||
|
||||
}
|
||||
# ... and then we call the whole thing.
|
||||
git_rebase__am
|
||||
|
|
|
@ -810,6 +810,17 @@ add_exec_commands () {
|
|||
mv "$1.new" "$1"
|
||||
}
|
||||
|
||||
# The whole contents of this file is run by dot-sourcing it from
|
||||
# inside a shell function. It used to be that "return"s we see
|
||||
# below were not inside any function, and expected to return
|
||||
# to the function that dot-sourced us.
|
||||
#
|
||||
# However, FreeBSD /bin/sh misbehaves on such a construct and
|
||||
# continues to run the statements that follow such a "return".
|
||||
# As a work-around, we introduce an extra layer of a function
|
||||
# here, and immediately call it after defining it.
|
||||
git_rebase__interactive () {
|
||||
|
||||
case "$action" in
|
||||
continue)
|
||||
# do we have anything to commit?
|
||||
|
@ -1042,3 +1053,7 @@ GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
|
|||
output git checkout $onto || die_abort "could not detach HEAD"
|
||||
git update-ref ORIG_HEAD $orig_head
|
||||
do_rest
|
||||
|
||||
}
|
||||
# ... and then we call the whole thing.
|
||||
git_rebase__interactive
|
||||
|
|
|
@ -101,6 +101,17 @@ finish_rb_merge () {
|
|||
say All done.
|
||||
}
|
||||
|
||||
# The whole contents of this file is run by dot-sourcing it from
|
||||
# inside a shell function. It used to be that "return"s we see
|
||||
# below were not inside any function, and expected to return
|
||||
# to the function that dot-sourced us.
|
||||
#
|
||||
# However, FreeBSD /bin/sh misbehaves on such a construct and
|
||||
# continues to run the statements that follow such a "return".
|
||||
# As a work-around, we introduce an extra layer of a function
|
||||
# here, and immediately call it after defining it.
|
||||
git_rebase__merge () {
|
||||
|
||||
case "$action" in
|
||||
continue)
|
||||
read_state
|
||||
|
@ -151,3 +162,7 @@ do
|
|||
done
|
||||
|
||||
finish_rb_merge
|
||||
|
||||
}
|
||||
# ... and then we call the whole thing.
|
||||
git_rebase__merge
|
||||
|
|
Loading…
Reference in a new issue