From 13420028e5b119d27277d521f4d267212c5ca21c Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 10 Nov 2023 11:01:15 +0100 Subject: [PATCH 1/4] global: convert trivial usages of `test -a/-o ` Our coding guidelines say to not use `test` with `-a` and `-o` because it can easily lead to bugs. Convert trivial cases where we still use these to instead instead concatenate multiple invocations of `test` via `&&` and `||`, respectively. While not all of the converted instances can cause ambiguity, it is worth getting rid of all of them regardless: - It becomes easier to reason about the code as we do not have to argue why one use of `-a`/`-o` is okay while another one isn't. - We don't encourage people to use these expressions. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- GIT-VERSION-GEN | 2 +- configure.ac | 2 +- contrib/subtree/git-subtree.sh | 4 ++-- t/perf/perf-lib.sh | 2 +- t/perf/run | 9 +++++---- t/valgrind/valgrind.sh | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index e54492f827..7246ab7c78 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -11,7 +11,7 @@ LF=' if test -f version then VN=$(cat version) || VN="$DEF_VER" -elif test -d ${GIT_DIR:-.git} -o -f .git && +elif { test -d "${GIT_DIR:-.git}" || test -f .git; } && VN=$(git describe --match "v[0-9]*" HEAD 2>/dev/null) && case "$VN" in *$LF*) (exit 1) ;; diff --git a/configure.ac b/configure.ac index 276593cd9d..d1a96da14e 100644 --- a/configure.ac +++ b/configure.ac @@ -94,7 +94,7 @@ AC_DEFUN([GIT_PARSE_WITH_SET_MAKE_VAR], [AC_ARG_WITH([$1], [AS_HELP_STRING([--with-$1=VALUE], $3)], if test -n "$withval"; then - if test "$withval" = "yes" -o "$withval" = "no"; then + if test "$withval" = "yes" || test "$withval" = "no"; then AC_MSG_WARN([You likely do not want either 'yes' or 'no' as] [a value for $1 ($2). Maybe you do...?]) fi diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index e0c5d3b0de..43b5fec732 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -489,13 +489,13 @@ find_existing_splits () { ;; END) debug "Main is: '$main'" - if test -z "$main" -a -n "$sub" + if test -z "$main" && test -n "$sub" then # squash commits refer to a subtree debug " Squash: $sq from $sub" cache_set "$sq" "$sub" fi - if test -n "$main" -a -n "$sub" + if test -n "$main" && test -n "$sub" then debug " Prior: $main -> $sub" cache_set $main $sub diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index e7786775a9..b952e5024b 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -31,7 +31,7 @@ unset GIT_CONFIG_NOSYSTEM GIT_CONFIG_SYSTEM="$TEST_DIRECTORY/perf/config" export GIT_CONFIG_SYSTEM -if test -n "$GIT_TEST_INSTALLED" -a -z "$PERF_SET_GIT_TEST_INSTALLED" +if test -n "$GIT_TEST_INSTALLED" && test -z "$PERF_SET_GIT_TEST_INSTALLED" then error "Do not use GIT_TEST_INSTALLED with the perf tests. diff --git a/t/perf/run b/t/perf/run index 34115edec3..486ead2198 100755 --- a/t/perf/run +++ b/t/perf/run @@ -91,10 +91,10 @@ set_git_test_installed () { run_dirs_helper () { mydir=${1%/} shift - while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do + while test $# -gt 0 && test "$1" != -- && test ! -f "$1"; do shift done - if test $# -gt 0 -a "$1" = --; then + if test $# -gt 0 && test "$1" = --; then shift fi @@ -124,7 +124,7 @@ run_dirs_helper () { } run_dirs () { - while test $# -gt 0 -a "$1" != -- -a ! -f "$1"; do + while test $# -gt 0 && test "$1" != -- && test ! -f "$1"; do run_dirs_helper "$@" shift done @@ -180,7 +180,8 @@ run_subsection () { GIT_PERF_AGGREGATING_LATER=t export GIT_PERF_AGGREGATING_LATER - if test $# = 0 -o "$1" = -- -o -f "$1"; then + if test $# = 0 || test "$1" = -- || test -f "$1" + then set -- . "$@" fi diff --git a/t/valgrind/valgrind.sh b/t/valgrind/valgrind.sh index 669ebaf68b..3c8ee19975 100755 --- a/t/valgrind/valgrind.sh +++ b/t/valgrind/valgrind.sh @@ -23,7 +23,7 @@ memcheck) VALGRIND_MAJOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*\([0-9]*\)') VALGRIND_MINOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*[0-9]*\.\([0-9]*\)') test 3 -gt "$VALGRIND_MAJOR" || - test 3 -eq "$VALGRIND_MAJOR" -a 4 -gt "$VALGRIND_MINOR" || + { test 3 -eq "$VALGRIND_MAJOR" && test 4 -gt "$VALGRIND_MINOR"; } || TOOL_OPTIONS="$TOOL_OPTIONS --track-origins=yes" ;; *) From 88983946fa00ebea8b346acab46e19bceeed427d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 10 Nov 2023 11:01:19 +0100 Subject: [PATCH 2/4] contrib/subtree: stop using `-o` to test for number of args Functions in git-subtree.sh all assert that they are being passed the correct number of arguments. In cases where we accept a variable number of arguments we assert this via a single call to `test` with `-o`, which is discouraged by our coding guidelines. Convert these cases to stop doing so. This requires us to decompose assertions of the style `assert test $# = 2 -o $# = 3` into two calls because we have no easy way to logically chain statements passed to the assert function. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- contrib/subtree/git-subtree.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 43b5fec732..8af0a81ba3 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -373,7 +373,8 @@ try_remove_previous () { # Usage: process_subtree_split_trailer SPLIT_HASH MAIN_HASH [REPOSITORY] process_subtree_split_trailer () { - assert test $# = 2 -o $# = 3 + assert test $# -ge 2 + assert test $# -le 3 b="$1" sq="$2" repository="" @@ -402,7 +403,8 @@ process_subtree_split_trailer () { # Usage: find_latest_squash DIR [REPOSITORY] find_latest_squash () { - assert test $# = 1 -o $# = 2 + assert test $# -ge 1 + assert test $# -le 2 dir="$1" repository="" if test "$#" = 2 @@ -455,7 +457,8 @@ find_latest_squash () { # Usage: find_existing_splits DIR REV [REPOSITORY] find_existing_splits () { - assert test $# = 2 -o $# = 3 + assert test $# -ge 2 + assert test $# -le 3 debug "Looking for prior splits..." local indent=$(($indent + 1)) @@ -916,7 +919,7 @@ cmd_split () { if test $# -eq 0 then rev=$(git rev-parse HEAD) - elif test $# -eq 1 -o $# -eq 2 + elif test $# -eq 1 || test $# -eq 2 then rev=$(git rev-parse -q --verify "$1^{commit}") || die "fatal: '$1' does not refer to a commit" @@ -1006,8 +1009,11 @@ cmd_split () { # Usage: cmd_merge REV [REPOSITORY] cmd_merge () { - test $# -eq 1 -o $# -eq 2 || + if test $# -lt 1 || test $# -gt 2 + then die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'" + fi + rev=$(git rev-parse -q --verify "$1^{commit}") || die "fatal: '$1' does not refer to a commit" repository="" From 47c39c28bc1a0001e4341ae70629adcb10f425cc Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 10 Nov 2023 11:01:24 +0100 Subject: [PATCH 3/4] contrib/subtree: convert subtree type check to use case statement The `subtree_for_commit ()` helper function asserts that the subtree identified by its parameters are either a commit or tree. This is done via the `-o` parameter of test, which is discouraged. Refactor the code to instead use a switch statement over the type. Despite being aligned with our coding guidelines, the resulting code is arguably also easier to read. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- contrib/subtree/git-subtree.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 8af0a81ba3..3028029ac2 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -641,10 +641,16 @@ subtree_for_commit () { while read mode type tree name do assert test "$name" = "$dir" - assert test "$type" = "tree" -o "$type" = "commit" - test "$type" = "commit" && continue # ignore submodules - echo $tree - break + + case "$type" in + commit) + continue;; # ignore submodules + tree) + echo $tree + break;; + *) + die "fatal: tree entry is of type ${type}, expected tree or commit";; + esac done || exit $? } From 615993d092269d62473b93fa29c944ca4e3bc18f Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Fri, 10 Nov 2023 11:01:28 +0100 Subject: [PATCH 4/4] Makefile: stop using `test -o` when unlinking duplicate executables When building executables we may end up with both `foo` and `foo.exe` in the project's root directory. This can cause issues on Cygwin, which is why we unlink the `foo` binary (see 6fc301bbf68 (Makefile: remove $foo when $foo.exe is built/installed., 2007-01-10)). This step is skipped if either: - `foo` is a directory, which can happen when building Git on Windows via MSVC (see ade2ca0ca9f (Do not try to remove directories when removing old links, 2009-10-27)). - `foo` is a hardlink to `foo.exe`, which can happen on Cygwin (see 0d768f7c8f1 (Makefile: building git in cygwin 1.7.0, 2008-08-15)). These two conditions are currently chained together via `test -o`, which is discouraged by our code style guide. Convert the recipe to instead use an `if` statement with `&&`'d conditions, which both matches our style guide and is easier to ready. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 03adcb5a48..1094a55771 100644 --- a/Makefile +++ b/Makefile @@ -2342,7 +2342,7 @@ profile-fast: profile-clean all:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS ifneq (,$X) - $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), test -d '$p' -o '$p' -ef '$p$X' || $(RM) '$p';) + $(QUIET_BUILT_IN)$(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_COMMANDS_TO_INSTALL) $(OTHER_PROGRAMS))), if test ! -d '$p' && test ! '$p' -ef '$p$X'; then $(RM) '$p'; fi;) endif all::