#!/bin/bash # # Copyright (C) 2026 Danilo M. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # The one runnable check for gitcfg. GIT_CONFIG_GLOBAL points git at a file # in a temp directory, so the real ~/.gitconfig is never read or written. # # Usage: ./test-gitcfg.sh (exit 0 = all passed) set -u here="$(cd "$(dirname "$0")" && pwd)" ctl="$here/gitcfg" tmp="$(mktemp -d)" trap 'rm -rf "$tmp"' EXIT export GIT_CONFIG_GLOBAL="$tmp/gitconfig" fail=0 check() { if [[ "$2" == "$3" ]]; then echo "ok $1" else echo "FAIL $1" printf ' want: %q\n got: %q\n' "$2" "$3" fail=1 fi } vals() { git config --global --get-all "$1" | paste -sd,; } # Values starting with a dash, as versionsort.prereleasesuffix holds, and a # comment that every write must leave alone. printf '# keep me\n[v]\n\ts = -rc\n\ts = -beta\n\ts = -alpha\n' > "$GIT_CONFIG_GLOBAL" check "list" $'v.s\n-rc|v.s\n-beta|v.s\n-alpha|' "$("$ctl" list | tr '\0' '|')" out="$("$ctl" set v.s -beta -BETA)"; rc=$? check "set one of three: rc" 0 "$rc" check "set one of three: silent" "" "$out" check "set one of three: values" "-rc,-BETA,-alpha" "$(vals v.s)" # git would append here and exit 0; gitcfg must refuse instead. out="$("$ctl" set v.s -gone x)"; rc=$? check "set missing old: rc" 1 "$rc" check "set missing old: says so" 1 "$([[ -n "$out" ]] && echo 1)" check "set missing old: nothing appended" "-rc,-BETA,-alpha" "$(vals v.s)" out="$("$ctl" unset v.s -rc)"; rc=$? check "unset one of three: rc" 0 "$rc" check "unset one of three: values" "-BETA,-alpha" "$(vals v.s)" out="$("$ctl" unset v.s -gone)"; rc=$? check "unset missing: rc" 1 "$rc" check "unset missing: says so" 1 "$([[ -n "$out" ]] && echo 1)" out="$("$ctl" add a.b "x=y")"; rc=$? check "add with =: rc" 0 "$rc" check "add with =: value" "x=y" "$(vals a.b)" out="$("$ctl" add "bad key" v)"; rc=$? check "add bad key: rc" 1 "$rc" check "add bad key: git's error" 1 "$([[ "$out" == *section* ]] && echo 1)" check "comment kept" 1 "$(grep -c '^# keep me$' "$GIT_CONFIG_GLOBAL")" # A value held twice: --fixed-value would replace or trip on both, so gitcfg # refuses rather than silently merging two rows into one. printf '[d]\n\tv = a\n\tv = a\n\tv = b\n' >> "$GIT_CONFIG_GLOBAL" out="$("$ctl" set d.v a c)"; rc=$? check "set duplicate: rc" 1 "$rc" check "set duplicate: untouched" "a,a,b" "$(vals d.v)" out="$("$ctl" unset d.v a)"; rc=$? check "unset duplicate: rc" 1 "$rc" check "unset duplicate: says why" 1 "$([[ "$out" == *twice* ]] && echo 1)" # A file git cannot parse lists nothing on stdout without this, which the # page would draw as an empty config. cp "$GIT_CONFIG_GLOBAL" "$tmp/good" printf '[x\n' >> "$GIT_CONFIG_GLOBAL" out="$("$ctl" list)"; rc=$? check "list broken file: rc" 1 "$rc" check "list broken file: error= line" 1 "$([[ "$out" == error=* ]] && echo 1)" cp "$tmp/good" "$GIT_CONFIG_GLOBAL" "$ctl" bogus >/dev/null 2>&1; rc=$? check "usage: rc" 2 "$rc" exit "$fail"