feat(git): deploy user-scope ~/.gitconfig from the repo template

Git never expands $VARS in its config, so gitconfig carries @USER@ and
@EMAIL@ placeholders that install.sh fills from the deployed bashrc's
USER/EMAIL exports. A differing ~/.gitconfig is kept as
~/.gitconfig.backup-<date>; an identical one is left alone. A repo's
.git/config still overrides it. excludesfile uses ~ (git expands it,
not $HOME).

The rc files now override $USER, so the installer takes the login name
from id -un for dscl and the code-server unit.
This commit is contained in:
Bastien CHANOT
2026-10-06 10:55:24 +02:00
parent 3b53213af4
commit 51521e7ca4
5 changed files with 97 additions and 7 deletions
+52 -4
View File
@@ -364,7 +364,8 @@ set_login_shell() {
if ! grep -qxF "$target" /etc/shells; then
echo "$target" | sudo tee -a /etc/shells >/dev/null
fi
current="$(dscl . -read "/Users/$USER" UserShell | awk '{ print $2 }')"
# id -un, not $USER: the deployed rc sets USER to the git/vim identity.
current="$(dscl . -read "/Users/$(id -un)" UserShell | awk '{ print $2 }')"
if [ "$current" = "$target" ]; then
echo "Login shell already $target — skipping"
return 0
@@ -429,6 +430,50 @@ wire_bash_profile() {
"$line" >> "$profile"
}
# Value of `export NAME=value` ($1) in the rc file $2, quotes stripped. The last
# match wins, as when the shell sources it. Empty when absent.
rc_export_value() {
sed -n "s/^export $1=//p" "$2" | tail -n 1 | tr -d "\"'"
}
# Print the repo gitconfig template with @USER@ and @EMAIL@ replaced by $1 and
# $2. Bash substitution, so the values need no sed escaping.
render_gitconfig() {
local name="$1" email="$2" line
while IFS= read -r line || [ -n "$line" ]; do
line="${line//@USER@/$name}"
line="${line//@EMAIL@/$email}"
printf '%s\n' "$line"
done < "$SCRIPT_DIR/gitconfig"
}
# Install the user-scope ~/.gitconfig (a repo's own .git/config still wins).
# The identity is read from the USER/EMAIL exports of the deployed rc ($1), so
# git and the shell agree. A ~/.gitconfig that differs is kept as
# ~/.gitconfig.backup-<date>, outside ~/Oldconfig which every run wipes.
# Idempotent: an identical ~/.gitconfig is left alone.
deploy_gitconfig() {
local rc="$1" name email rendered backup
name="$(rc_export_value USER "$rc")"
email="$(rc_export_value EMAIL "$rc")"
if [ -z "$name" ] || [ -z "$email" ]; then
echo "USER/EMAIL not exported by $rc — skipping ~/.gitconfig" >&2
return 0
fi
rendered="$(render_gitconfig "$name" "$email")"
if printf '%s\n' "$rendered" | cmp -s - "$HOME/.gitconfig"; then
echo "$HOME/.gitconfig already up to date — skipping"
return 0
fi
if [ -e "$HOME/.gitconfig" ]; then
backup="$HOME/.gitconfig.backup-$(date +%Y%m%d-%H%M%S)"
echo "Saving the current ~/.gitconfig to $backup"
mv "$HOME/.gitconfig" "$backup"
fi
echo "Deploying gitconfig to ~/.gitconfig ($name <$email>)"
printf '%s\n' "$rendered" > "$HOME/.gitconfig"
}
# What the Linux install sets up that this macOS run did not, and why.
print_macos_gaps() {
cat <<'EOF'
@@ -463,8 +508,7 @@ if command -v apt-get >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get upgrade -y
# Build + version control + C dev tooling (gitleaks backs the pre-commit hook).
# Web stack: MariaDB + PHP modules for local WordPress/LAMP work; the php-* metapackages
# Build + version control + C dev tooling (gitleaks backs the pre-commit hook). # Web stack: MariaDB + PHP modules for local WordPress/LAMP work; the php-* metapackages
# follow the distro's PHP version instead of pinning php8.x-*.
sudo apt-get install -y \
vim git git-lfs git-filter-repo gitleaks gcc make pkg-config dkms valgrind shellcheck \
@@ -483,7 +527,8 @@ if command -v apt-get >/dev/null 2>&1; then
if ! command -v code-server >/dev/null 2>&1; then
curl -fsSL https://code-server.dev/install.sh | sh
fi
sudo systemctl enable --now "code-server@$USER"
# id -un, not $USER: the deployed bashrc sets USER to the git/vim identity.
sudo systemctl enable --now "code-server@$(id -un)"
# GNOME desktop (GDM + Shell): the RDP remote login below needs a GNOME session
# to hand out; a bare server install has none. Ubuntu-only metapackage.
@@ -558,6 +603,9 @@ fi
echo "Deploying $bashrc"
cp "$SCRIPT_DIR/$bashrc" "$HOME/.bashrc"
# User-scope git config, identity taken from the bashrc just deployed.
deploy_gitconfig "$SCRIPT_DIR/$bashrc"
# Python CLIs via pipx (run as the user, never sudo). Skipped if pipx is absent.
if command -v pipx >/dev/null 2>&1; then
echo "Installing pipx CLIs (PyMuPDF -> pymupdf, Markdown -> markdown_py)"