set -euo pipefail BR="ext" REMOTE="origin" DATE_TAG="$(date -u +'%Y%m%d-%H%M%S')" BACKUP_TAG="backup/${BR}-pre-truncate-${DATE_TAG}" # 1) Pré-vol git fetch --prune "${REMOTE}" test -z "$(git status --porcelain)" # fail si index sale git rev-parse --verify "${BR}" >/dev/null git ls-remote --exit-code "${REMOTE}" "refs/heads/${BR}" >/dev/null # 2) Mémos de contrôle echo "[INFO] Avant: 5 derniers SHAs sur ${BR}" git rev-list --max-count=5 "${BR}" | tee /tmp/pre_last5.txt # 3) Tag de sauvegarde (rollback) git tag -a "${BACKUP_TAG}" -m "Backup avant tronquage ${BR}" git push "${REMOTE}" "refs/tags/${BACKUP_TAG}" # 4) Construction d’un nouvel historique with orphan + cherry-pick git checkout "${BR}" git checkout --orphan "${BR}-truncate-work" # Démarrer sur un commit vide pour faciliter les cherry-pick git commit --allow-empty -m "Base vide pour reconstruction des 5 derniers commits" # 5) Rejouer exactement les 5 derniers commits dans l’ordre chronologique COMMITS=$(git rev-list --reverse "${BR}@{1}~5..${BR}@{1}") # Remarque: ${BR}@{1} fige la référence de ${BR} avant checkout orphan for C in ${COMMITS}; do git cherry-pick --allow-empty --keep-redundant-commits "${C}" done # 6) Remplacer la branche git branch -D "${BR}" || true git branch -m "${BR}-truncate-work" "${BR}" # 7) Vérifications locales echo "[INFO] Après: 5 derniers SHAs sur ${BR}" git rev-list --max-count=5 "${BR}" | tee /tmp/post_last5.txt diff -u /tmp/pre_last5.txt /tmp/post_last5.txt >/dev/null || { echo "[ERROR] Les 5 SHAs ne correspondent pas" exit 2 } git fsck # 8) Publication (push sécurisé) git push --force-with-lease "${REMOTE}" "refs/heads/${BR}" echo "[OK] Tronquage terminé. Tag de secours: ${BACKUP_TAG}"