252 lines
6.4 KiB
Bash
Executable File
252 lines
6.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -u
|
|
|
|
die() {
|
|
echo "ERROR: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
section() {
|
|
printf '\n=== %s ===\n' "$1"
|
|
}
|
|
|
|
val() {
|
|
[ -n "${1:-}" ] && printf '%s' "$1" || printf '%s' "-"
|
|
}
|
|
|
|
git rev-parse --is-inside-work-tree >/dev/null 2>&1 \
|
|
|| die "Not inside a Git repository"
|
|
|
|
ROOT=$(git rev-parse --show-toplevel)
|
|
BRANCH=$(git symbolic-ref --quiet --short HEAD 2>/dev/null || echo "DETACHED")
|
|
HEAD_COMMIT=$(git rev-parse --short=12 HEAD)
|
|
|
|
cd "$ROOT" || exit 1
|
|
|
|
# ------------------------------------------------------------
|
|
section "REPOSITORY"
|
|
|
|
echo "path : $ROOT"
|
|
echo "branch : $BRANCH"
|
|
echo "HEAD : $HEAD_COMMIT"
|
|
|
|
# ------------------------------------------------------------
|
|
section "IDENTITY"
|
|
|
|
GLOBAL_NAME=$(git config --global --get user.name 2>/dev/null || true)
|
|
GLOBAL_EMAIL=$(git config --global --get user.email 2>/dev/null || true)
|
|
|
|
LOCAL_NAME=$(git config --local --get user.name 2>/dev/null || true)
|
|
LOCAL_EMAIL=$(git config --local --get user.email 2>/dev/null || true)
|
|
|
|
EFFECTIVE_NAME=$(git config --get user.name 2>/dev/null || true)
|
|
EFFECTIVE_EMAIL=$(git config --get user.email 2>/dev/null || true)
|
|
|
|
printf 'global : %s <%s>\n' "$(val "$GLOBAL_NAME")" "$(val "$GLOBAL_EMAIL")"
|
|
printf 'local : %s <%s>\n' "$(val "$LOCAL_NAME")" "$(val "$LOCAL_EMAIL")"
|
|
printf 'effective : %s <%s>\n' "$(val "$EFFECTIVE_NAME")" "$(val "$EFFECTIVE_EMAIL")"
|
|
|
|
# ------------------------------------------------------------
|
|
section "REMOTES"
|
|
|
|
for remote in $(git remote); do
|
|
FETCH_URL=$(git remote get-url "$remote" 2>/dev/null || true)
|
|
PUSH_URL=$(git remote get-url --push "$remote" 2>/dev/null || true)
|
|
|
|
echo
|
|
echo "[$remote]"
|
|
echo " fetch : $(val "$FETCH_URL")"
|
|
echo " push : $(val "$PUSH_URL")"
|
|
done
|
|
|
|
# ------------------------------------------------------------
|
|
section "SUBMODULES"
|
|
|
|
if [ ! -f .gitmodules ]; then
|
|
echo "(none)"
|
|
else
|
|
git config -f .gitmodules \
|
|
--get-regexp '^submodule\..*\.path$' 2>/dev/null |
|
|
while read -r key path; do
|
|
|
|
name=${key#submodule.}
|
|
name=${name%.path}
|
|
|
|
declared=$(
|
|
git config -f .gitmodules \
|
|
--get "submodule.$name.url" 2>/dev/null || true
|
|
)
|
|
|
|
resolved=$(
|
|
git config \
|
|
--get "submodule.$name.url" 2>/dev/null || true
|
|
)
|
|
|
|
commit=$(
|
|
git ls-tree HEAD "$path" 2>/dev/null |
|
|
awk '{print $3}'
|
|
)
|
|
|
|
echo
|
|
echo "[$name]"
|
|
echo " path : $path"
|
|
echo " declared : $(val "$declared")"
|
|
echo " resolved : $(val "$resolved")"
|
|
echo " commit : $(val "$commit")"
|
|
done
|
|
fi
|
|
|
|
# ------------------------------------------------------------
|
|
section "SSH ALIASES"
|
|
|
|
SSH_CONFIG="$HOME/.ssh/config"
|
|
|
|
if [ ! -f "$SSH_CONFIG" ]; then
|
|
echo "(no ~/.ssh/config)"
|
|
else
|
|
awk '
|
|
/^Host[ \t]+/ {
|
|
host=$0
|
|
sub(/^[ \t]*Host[ \t]+/, "", host)
|
|
print ""
|
|
print "[" host "]"
|
|
next
|
|
}
|
|
|
|
/^[ \t]*(HostName|User|Port|IdentityFile|IdentitiesOnly)[ \t]+/ {
|
|
key=$1
|
|
value=$2
|
|
printf " %-15s %s\n", key ":", value
|
|
}
|
|
' "$SSH_CONFIG"
|
|
fi
|
|
|
|
# ------------------------------------------------------------
|
|
section "SSH BY REMOTE"
|
|
|
|
for remote in $(git remote); do
|
|
|
|
url=$(git remote get-url "$remote" 2>/dev/null || true)
|
|
|
|
case "$url" in
|
|
ssh://*)
|
|
;;
|
|
*@*:*)
|
|
;;
|
|
*)
|
|
echo
|
|
echo "[$remote]"
|
|
echo " protocol : non-SSH"
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
# Extract SSH destination from URL.
|
|
if [[ "$url" =~ ^ssh://([^/@]+@)?([^/:]+)(:([0-9]+))?/.*$ ]]; then
|
|
url_user=${BASH_REMATCH[1]%@}
|
|
url_host=${BASH_REMATCH[2]}
|
|
url_port=${BASH_REMATCH[4]}
|
|
elif [[ "$url" =~ ^([^@]+)@([^:]+):.*$ ]]; then
|
|
url_user=${BASH_REMATCH[1]}
|
|
url_host=${BASH_REMATCH[2]}
|
|
url_port=""
|
|
else
|
|
echo
|
|
echo "[$remote]"
|
|
echo " unable to parse: $url"
|
|
continue
|
|
fi
|
|
|
|
SSH_OUTPUT=$(ssh -G "$url_host" 2>/dev/null || true)
|
|
|
|
cfg_user=$(printf '%s\n' "$SSH_OUTPUT" |
|
|
awk '$1=="user" {print $2; exit}')
|
|
|
|
cfg_host=$(printf '%s\n' "$SSH_OUTPUT" |
|
|
awk '$1=="hostname" {print $2; exit}')
|
|
|
|
cfg_port=$(printf '%s\n' "$SSH_OUTPUT" |
|
|
awk '$1=="port" {print $2; exit}')
|
|
|
|
cfg_keys=$(printf '%s\n' "$SSH_OUTPUT" |
|
|
awk '$1=="identityfile" {print $2}')
|
|
|
|
effective_user=${url_user:-$cfg_user}
|
|
effective_port=${url_port:-$cfg_port}
|
|
|
|
echo
|
|
echo "[$remote]"
|
|
echo " URL : $url"
|
|
echo " URL user : $(val "$url_user")"
|
|
echo " URL host : $(val "$url_host")"
|
|
echo " URL port : $(val "$url_port")"
|
|
echo
|
|
echo " SSH cfg user : $(val "$cfg_user")"
|
|
echo " SSH cfg host : $(val "$cfg_host")"
|
|
echo " SSH cfg port : $(val "$cfg_port")"
|
|
|
|
while read -r key; do
|
|
[ -n "$key" ] && echo " identity : $key"
|
|
done <<< "$cfg_keys"
|
|
|
|
echo
|
|
echo " effective user: $(val "$effective_user")"
|
|
echo " effective host: $(val "$cfg_host")"
|
|
echo " effective port: $(val "$effective_port")"
|
|
|
|
if [ -n "$url_user" ] &&
|
|
[ -n "$cfg_user" ] &&
|
|
[ "$url_user" != "$cfg_user" ]; then
|
|
echo " NOTICE : URL user overrides SSH config user"
|
|
fi
|
|
|
|
if [ -n "$url_port" ] &&
|
|
[ -n "$cfg_port" ] &&
|
|
[ "$url_port" != "$cfg_port" ]; then
|
|
echo " NOTICE : URL port overrides SSH config port"
|
|
fi
|
|
done
|
|
|
|
# ------------------------------------------------------------
|
|
section "SSH AGENT"
|
|
|
|
if ssh-add -l >/dev/null 2>&1; then
|
|
ssh-add -l
|
|
else
|
|
echo "INFO: no SSH agent available or no key loaded"
|
|
fi
|
|
|
|
# ------------------------------------------------------------
|
|
section "OBSERVATIONS"
|
|
|
|
OBS=0
|
|
|
|
if [ -n "$LOCAL_NAME$LOCAL_EMAIL" ] &&
|
|
{ [ "$LOCAL_NAME" != "$GLOBAL_NAME" ] ||
|
|
[ "$LOCAL_EMAIL" != "$GLOBAL_EMAIL" ]; }; then
|
|
|
|
echo "NOTICE: local Git identity overrides global identity"
|
|
OBS=$((OBS + 1))
|
|
fi
|
|
|
|
if [ -f .gitmodules ]; then
|
|
while read -r key url; do
|
|
case "$url" in
|
|
../*|./*)
|
|
echo "INFO: relative submodule URL: $key -> $url"
|
|
OBS=$((OBS + 1))
|
|
;;
|
|
esac
|
|
done < <(
|
|
git config -f .gitmodules \
|
|
--get-regexp '^submodule\..*\.url$' 2>/dev/null
|
|
)
|
|
fi
|
|
|
|
if [ "$OBS" -eq 0 ]; then
|
|
echo "No notable configuration difference detected."
|
|
fi
|
|
|
|
echo
|