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

[PATCH] Allow shell scripts to run with non-Bash /bin/sh

From
EREygene Ryabinkin <rea-git@codelabs.ru>
Date
Sep 21, 2007, 21:43 UTC
Message-ID
<20070921214346.GF97288@void.codelabs.ru>
Good day.

I had found that FreeBSD's /bin/sh refuses to work with git 1.5.3.2. correctly: no flags are recognized. The details and fix are below. I don't currently know if the Bash's behaviour is POSIXly correct or the 'case' statement semantics is not very well defined. But the following patch fixes the things for the FreeBSD.

Here we go.
-----

Option parsing in the Git shell scripts uses the construct 'while case "$#" in 0) break ;; esac; do ... done'. This is neat, because it needs no external commands invocation. But in the case when /bin/sh is not GNU Bash (for example, on FreeBSD) this cycle will not be executed at all.

The fix is to add the case branch '*) : ;;'. It also needs no external commands invocation and it does its work, because ':' always returns zero.

Signed-off-by: Eygene Ryabinkin <rea-git@codelabs.ru>
---
 git-am.sh                  |    2 +-
 git-clean.sh               |    2 +-
 git-commit.sh              |    2 +-
 git-fetch.sh               |    2 +-
 git-filter-branch.sh       |    2 +-
 git-instaweb.sh            |    2 +-
 git-ls-remote.sh           |    2 +-
 git-merge.sh               |    2 +-
 git-mergetool.sh           |    2 +-
 git-pull.sh                |    2 +-
 git-quiltimport.sh         |    2 +-
 git-rebase--interactive.sh |    2 +-
 git-rebase.sh              |    2 +-
 git-repack.sh              |    2 +-
 git-reset.sh               |    2 +-
 git-submodule.sh           |    2 +-
 16 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/git-am.sh b/git-am.sh
index 6809aa0..0bd8d34 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -109,7 +109,7 @@ dotest=.dotest sign= utf8=t keep= skip= interactive= resolved= binary=
 resolvemsg= resume=
 git_apply_opt=
 
-while case "$#" in 0) break;; esac
+while case "$#" in 0) break;; *) : ;; esac
 do
 	case "$1" in
 	-d=*|--d=*|--do=*|--dot=*|--dote=*|--dotes=*|--dotest=*)
diff --git a/git-clean.sh b/git-clean.sh
index a5cfd9f..1fac731 100755
--- a/git-clean.sh
+++ b/git-clean.sh
@@ -26,7 +26,7 @@ rmrf="rm -rf --"
 rm_refuse="echo Not removing"
 echo1="echo"
 
-while case "$#" in 0) break ;; esac
+while case "$#" in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	-d)
diff --git a/git-commit.sh b/git-commit.sh
index bb113e8..5f298c1 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -89,7 +89,7 @@ force_author=
 only_include_assumed=
 untracked_files=
 templatefile="`git config commit.template`"
-while case "$#" in 0) break;; esac
+while case "$#" in 0) break;; *) : ;; esac
 do
 	case "$1" in
 	-F|--F|-f|--f|--fi|--fil|--file)
diff --git a/git-fetch.sh b/git-fetch.sh
index c3a2001..dac2d72 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -27,7 +27,7 @@ shallow_depth=
 no_progress=
 test -t 1 || no_progress=--no-progress
 quiet=
-while case "$#" in 0) break ;; esac
+while case "$#" in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	-a|--a|--ap|--app|--appe|--appen|--append)
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index a4b6577..02b567b 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -105,7 +105,7 @@ filter_tag_name=
 filter_subdir=
 orig_namespace=refs/original/
 force=
-while case "$#" in 0) usage;; esac
+while case "$#" in 0) usage;; *) : ;; esac
 do
 	case "$1" in
 	--)
diff --git a/git-instaweb.sh b/git-instaweb.sh
index b79c6b6..c85f8c0 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -61,7 +61,7 @@ stop_httpd () {
 	test -f "$fqgitdir/pid" && kill `cat "$fqgitdir/pid"`
 }
 
-while case "$#" in 0) break ;; esac
+while case "$#" in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	--stop|stop)
diff --git a/git-ls-remote.sh b/git-ls-remote.sh
index b7e5d04..4ef4341 100755
--- a/git-ls-remote.sh
+++ b/git-ls-remote.sh
@@ -13,7 +13,7 @@ die () {
 }
 
 exec=
-while case "$#" in 0) break;; esac
+while case "$#" in 0) break;; *) : ;; esac
 do
   case "$1" in
   -h|--h|--he|--hea|--head|--heads)
diff --git a/git-merge.sh b/git-merge.sh
index 3a01db0..94a50aa 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -122,7 +122,7 @@ merge_name () {
 case "$#" in 0) usage ;; esac
 
 have_message=
-while case "$#" in 0) break ;; esac
+while case "$#" in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
diff --git a/git-mergetool.sh b/git-mergetool.sh
index 47a8055..0e286dd 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -268,7 +268,7 @@ merge_file () {
     cleanup_temp_files
 }
 
-while case $# in 0) break ;; esac
+while case $# in 0) break ;; *) : ;; esac
 do
     case "$1" in
 	-t|--tool*)
diff --git a/git-pull.sh b/git-pull.sh
index 5e96d1f..722ed4e 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -16,7 +16,7 @@ test -z "$(git ls-files -u)" ||
 	die "You are in the middle of a conflicted merge."
 
 strategy_args= no_summary= no_commit= squash=
-while case "$#,$1" in 0) break ;; *,-*) ;; *) break ;; esac
+while case "$#,$1" in 0) break ;; *,-*) : ;; *) break ;; esac
 do
 	case "$1" in
 	-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
diff --git a/git-quiltimport.sh b/git-quiltimport.sh
index 9de54d1..4039617 100755
--- a/git-quiltimport.sh
+++ b/git-quiltimport.sh
@@ -5,7 +5,7 @@ SUBDIRECTORY_ON=Yes
 
 dry_run=""
 quilt_author=""
-while case "$#" in 0) break;; esac
+while case "$#" in 0) break;; *) : ;; esac
 do
 	case "$1" in
 	--au=*|--aut=*|--auth=*|--autho=*|--author=*)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index abc2b1c..54e4299 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -317,7 +317,7 @@ do_rest () {
 	done
 }
 
-while case $# in 0) break ;; esac
+while case $# in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	--continue)
diff --git a/git-rebase.sh b/git-rebase.sh
index 3bd66b0..f7ae22c 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -122,7 +122,7 @@ finish_rb_merge () {
 
 is_interactive () {
 	test -f "$dotest"/interactive ||
-	while case $#,"$1" in 0,|*,-i|*,--interactive) break ;; esac
+	while case $#,"$1" in 0,|*,-i|*,--interactive) break ;; *) : ;; esac
 	do
 		shift
 	done && test -n "$1"
diff --git a/git-repack.sh b/git-repack.sh
index 156c5e8..aac771e 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -9,7 +9,7 @@ SUBDIRECTORY_OK='Yes'
 
 no_update_info= all_into_one= remove_redundant=
 local= quiet= no_reuse= extra=
-while case "$#" in 0) break ;; esac
+while case "$#" in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	-n)	no_update_info=t ;;
diff --git a/git-reset.sh b/git-reset.sh
index 1dc606f..eb92610 100755
--- a/git-reset.sh
+++ b/git-reset.sh
@@ -11,7 +11,7 @@ require_work_tree
 update= reset_type=--mixed
 unset rev
 
-while case $# in 0) break ;; esac
+while case $# in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	--mixed | --soft | --hard)
diff --git a/git-submodule.sh b/git-submodule.sh
index 3320998..78a25ad 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -251,7 +251,7 @@ modules_list()
 	done
 }
 
-while case "$#" in 0) break ;; esac
+while case "$#" in 0) break ;; *) : ;; esac
 do
 	case "$1" in
 	add)
-- 
1.5.3.2
-- 
Eygene
Next: Junio C Hamano
Message 1 of 45 in “Allow shell scripts to run with non-Bash /bin/sh”
  1. Allow shell scripts to run with non-Bash /bin/shEygene Ryabinkin, Sep 21, 2007
  2. Junio C HamanoSep 21, 2007
  3. David KastrupSep 22, 2007
  4. Junio C HamanoSep 22, 2007
  5. Junio C HamanoSep 22, 2007
  6. David KastrupSep 22, 2007
  7. Junio C HamanoSep 22, 2007
  8. Eygene RyabinkinSep 22, 2007
  9. David KastrupSep 22, 2007
  10. Junio C HamanoSep 22, 2007
  11. Vineet KumarSep 22, 2007
  12. David KastrupSep 22, 2007
  13. Junio C HamanoSep 22, 2007
  14. Adam FlottSep 22, 2007
  15. Junio C HamanoSep 22, 2007
  16. Eygene RyabinkinSep 23, 2007
  17. David KastrupSep 23, 2007
  18. Junio C HamanoSep 23, 2007
  19. David KastrupSep 23, 2007
  20. Supplant the "while case ... break ;; esac" idiomDavid Kastrup, Sep 23, 2007
  21. Junio C HamanoSep 23, 2007
  22. David KastrupSep 24, 2007
  23. David KastrupSep 24, 2007
  24. Junio C HamanoSep 24, 2007
  25. David KastrupSep 25, 2007
  26. Junio C HamanoSep 25, 2007
  27. Johannes SchindelinSep 25, 2007
  28. Avi KivitySep 25, 2007
  29. Mike HommeySep 24, 2007
  30. David KastrupSep 24, 2007
  31. David SymondsSep 24, 2007
  32. David KastrupSep 24, 2007
  33. Pierre HabouzitSep 24, 2007
  34. Pierre HabouzitSep 24, 2007
  35. Johannes SchindelinSep 24, 2007
  36. Miles BaderSep 24, 2007
  37. Eygene RyabinkinSep 24, 2007
  38. Miles BaderSep 24, 2007
  39. David KastrupSep 24, 2007
  40. Johannes SchindelinSep 24, 2007
  41. David KastrupSep 24, 2007
  42. Miles BaderSep 24, 2007
  43. Junio C HamanoSep 24, 2007
  44. David KastrupSep 24, 2007
  45. David KastrupSep 24, 2007

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.