[ADDED] Script backlog.sh para recuperar repositorio o archivos de un commit específico

This commit is contained in:
Mauro Rosero P. 2025-04-01 20:53:23 -05:00
parent a5e1cf5787
commit de26489b2a
Signed by: mrosero
GPG key ID: 83BD2A5F674B7E26
2 changed files with 317 additions and 0 deletions

View file

@ -100,6 +100,7 @@ MRDevs Tools utiliza una estructura organizada que separa el código (en ~/devs)
| Comando | Descripción |
|---------|-------------|
| `bin/backlog.sh <commit_id>` | Revierte el repositorio o archivos específicos al estado de un commit concreto |
| `bin/ghadmin_install.sh` | Instala GitHub CLI (gh) con soporte multiplataforma |
| `bin/gladmin_install.sh` | Instala GitLab CLI (glab) con múltiples métodos de instalación |
| `bin/fjadmin_install.sh` | Instala Forgejo CLI (berg) para administración de Forgejo/Codeberg |
@ -140,6 +141,31 @@ El directorio `$HOME/devs` sirve como área principal de desarrollo donde se ges
Si desea usar Docker en lugar de Podman, debe instalarlo manualmente antes de ejecutar `bootstrap.sh`.
### Gestión Avanzada de Repositorios Git
```bash
# Revertir todo el repositorio a un commit específico
bin/backlog.sh a1b2c3d
# Recuperar solo un archivo específico desde un commit
bin/backlog.sh a1b2c3d --file src/config.js
# Recuperar múltiples archivos usando un patrón
bin/backlog.sh a1b2c3d --files "*.js"
# Ver solo la lista de archivos modificados en un commit
bin/backlog.sh a1b2c3d --list
# Ver la ayuda completa del comando
bin/backlog.sh --help
```
El script `backlog.sh` permite recuperar estados previos del repositorio con varias opciones de seguridad:
- Crea ramas de respaldo automáticamente antes de realizar cambios
- Ofrece guardar cambios no confirmados en stash
- Proporciona confirmaciones interactivas antes de acciones potencialmente destructivas
- Incluye instrucciones para deshacer los cambios si fuera necesario
### Configuración de Herramientas de IA
MRDevs Tools facilita el trabajo con herramientas de IA:

291
bin/backlog.sh Executable file
View file

@ -0,0 +1,291 @@
#!/bin/bash
#Script : backlog.sh
#Apps : MRDEVS TOOLS
#Description : Revierte el repositorio o archivos específicos al estado de un commit
#Author : Cortana Rosero One <cortana@rosero.one>
#Company Email : mauro@rosero.one
#Personal Email : cortana@rosero.one
#Created : 2025-04-01 10:00:00
#Modified : 2025-04-01 11:30:00
#Version : 1.3.1
#Use Notes : ./backlog.sh <commit_id> [--file <archivo>] [--files <patrón>]
#==============================================================================
# Derechos de Autor 2025 Mauro Rosero P. <mauro@rosero.one>
#==============================================================================
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
# bajo los términos de la Licencia Pública Affero General de GNU tal como
# lo publica la Free Software Foundation, ya sea la versión 3 de la licencia,
# o (a su elección) cualquier versión posterior.
#
# Este programa se distribuye con la esperanza de que sea útil,
# pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la
# Licencia Pública Affero General de GNU para obtener más detalles.
#
# Debería haber recibido una copia de la Licencia Pública Affero General
# junto con este programa. Si no la recibió, consulte <https://www.gnu.org/licenses/>.
# Definir variables básicas
BIN_HOME=${HOME}/devs
BIN_BASE=bin
# Mostrar ayuda
function mostrar_ayuda {
echo "Uso: $0 <commit_id> [opciones]"
echo ""
echo "Opciones:"
echo " --full Revierte todo el repositorio al commit especificado (por defecto)"
echo " --file <archivo> Revierte un archivo específico al estado del commit"
echo " --files <patrón> Revierte archivos que coincidan con un patrón"
echo " --list Lista los archivos modificados en el commit sin revertir nada"
echo " --help Muestra esta ayuda"
echo ""
echo "Ejemplos:"
echo " $0 abc123 # Revierte todo el repositorio al commit abc123"
echo " $0 abc123 --file src/main.js # Revierte solo src/main.js al estado del commit abc123"
echo " $0 abc123 --files \"*.js\" # Revierte todos los archivos .js al estado del commit abc123"
echo " $0 abc123 --list # Muestra los archivos que cambiaron en el commit abc123"
exit 0
}
# Verificar si hay suficientes parámetros
if [ $# -lt 1 ]; then
echo "Error: Se requiere un commit_id como parámetro."
mostrar_ayuda
exit 1
fi
# Inicializar variables
COMMIT_ID="$1"
shift
MODO="full"
ARCHIVO=""
PATRON=""
# Procesar argumentos adicionales
while [ "$#" -gt 0 ]; do
case "$1" in
--help)
mostrar_ayuda
;;
--full)
MODO="full"
;;
--file)
MODO="file"
ARCHIVO="$2"
if [ -z "$ARCHIVO" ]; then
echo "Error: Falta el nombre del archivo después de --file"
exit 1
fi
shift
;;
--files)
MODO="files"
PATRON="$2"
if [ -z "$PATRON" ]; then
echo "Error: Falta el patrón después de --files"
exit 1
fi
shift
;;
--list)
MODO="list"
;;
*)
echo "Error: Opción desconocida: $1"
mostrar_ayuda
exit 1
;;
esac
shift
done
# Verificar si estamos en un repositorio git
if ! git rev-parse --is-inside-work-tree > /dev/null 2>&1; then
echo "Error: Este comando debe ejecutarse dentro de un repositorio git."
exit 1
fi
# Verificar si el commit_id existe
if ! git rev-parse --verify "$COMMIT_ID^{commit}" >/dev/null 2>&1; then
echo "Error: El commit_id '$COMMIT_ID' no existe en este repositorio."
echo "Buscando referencias a ese commit_id..."
# Intentar encontrar commits parciales
POSIBLES_COMMITS=$(git log --all --pretty=format:"%h %s" | grep -i "$COMMIT_ID")
if [ -n "$POSIBLES_COMMITS" ]; then
echo "Posibles coincidencias encontradas:"
echo "$POSIBLES_COMMITS"
exit 1
fi
echo "No se encontraron referencias al commit proporcionado."
exit 1
fi
# Si el modo es "list", mostrar los archivos modificados y salir
if [ "$MODO" = "list" ]; then
echo "📋 Archivos modificados en el commit $COMMIT_ID:"
git show --name-status "$COMMIT_ID" | grep -E "^[AMD]" | sort
exit 0
fi
# Verificar si hay cambios sin confirmar
if ! git diff --quiet || ! git diff --cached --quiet; then
echo "⚠️ ADVERTENCIA: Hay cambios sin confirmar en tu repositorio."
if [ "$MODO" = "full" ]; then
echo "Estos cambios se perderán si continúas con la reversión completa."
else
echo "Estos cambios podrían causar conflictos con los archivos que intentas recuperar."
fi
read -p "¿Deseas guardar estos cambios en un stash? (s/n): " respuesta
if [[ "$respuesta" == "s" || "$respuesta" == "S" ]]; then
STASH_NAME="stash_before_reset_to_${COMMIT_ID}_$(date +%Y%m%d_%H%M%S)"
git stash push -m "$STASH_NAME"
echo "Cambios guardados en stash: $STASH_NAME"
fi
fi
# Crear una rama de respaldo antes de hacer cualquier cambio (si es reversión completa)
if [ "$MODO" = "full" ]; then
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse HEAD)
BACKUP_BRANCH="backup_${CURRENT_BRANCH}_before_reset_$(date +%Y%m%d_%H%M%S)"
echo "Creando rama de respaldo '$BACKUP_BRANCH'..."
git branch "$BACKUP_BRANCH"
# Obtener información del commit para el resumen
COMMIT_INFO=$(git show --quiet --format="%h - %s (%an, %ad)" --date=format:"%Y-%m-%d %H:%M:%S" "$COMMIT_ID")
echo "⚠️ ADVERTENCIA: Estás a punto de revertir TODO el repositorio al commit:"
echo "$COMMIT_INFO"
echo "Todos los cambios posteriores a este commit se perderán."
echo "Se ha creado una rama de respaldo: $BACKUP_BRANCH"
read -p "¿Estás seguro de que quieres continuar? (s/n): " confirmacion
if [[ "$confirmacion" != "s" && "$confirmacion" != "S" ]]; then
echo "Operación cancelada por el usuario."
exit 0
fi
echo "Revirtiendo todo el repositorio al commit $COMMIT_ID..."
# Realizar la reversión usando reset (se perderán todos los cambios locales)
git reset --hard "$COMMIT_ID"
if [ $? -eq 0 ]; then
echo "✅ Repositorio revertido exitosamente al commit: $COMMIT_ID"
echo "Información del commit:"
git show --quiet --format="%h - %s%n%nAutor: %an <%ae>%nFecha: %ad%n%n%b" --date=format:"%Y-%m-%d %H:%M:%S" "$COMMIT_ID"
echo ""
echo "Para recuperar los cambios anteriores, puedes usar la rama de respaldo:"
echo " git checkout $BACKUP_BRANCH"
echo ""
echo "Si necesitas empujar este cambio a un repositorio remoto, usa:"
echo " git push --force origen $CURRENT_BRANCH"
echo ""
echo "⚠️ ADVERTENCIA: El uso de git push --force puede causar problemas en repositorios compartidos."
else
echo "❌ Error al revertir al commit $COMMIT_ID"
echo "Puedes intentar manualmente con:"
echo " git reset --hard $COMMIT_ID"
fi
elif [ "$MODO" = "file" ]; then
# Verificar si el archivo existía en el commit
if ! git ls-tree -r "$COMMIT_ID" --name-only | grep -q "^$ARCHIVO$"; then
echo "⚠️ El archivo '$ARCHIVO' no existía en el commit $COMMIT_ID o la ruta es incorrecta."
echo "Archivos disponibles en ese commit que coinciden parcialmente:"
git ls-tree -r "$COMMIT_ID" --name-only | grep -i "$(basename "$ARCHIVO")"
exit 1
fi
echo "Recuperando el archivo '$ARCHIVO' desde el commit $COMMIT_ID..."
# Crear directorio temporal
TEMP_DIR=$(mktemp -d)
# Extraer el archivo del commit
git show "$COMMIT_ID:$ARCHIVO" > "$TEMP_DIR/$(basename "$ARCHIVO")" 2>/dev/null
if [ $? -ne 0 ]; then
echo "❌ Error al recuperar el archivo del commit."
rm -rf "$TEMP_DIR"
exit 1
fi
# Crear directorio para el archivo si no existe
ARCHIVO_DIR=$(dirname "$ARCHIVO")
if [ "$ARCHIVO_DIR" != "." ] && [ ! -d "$ARCHIVO_DIR" ]; then
mkdir -p "$ARCHIVO_DIR"
fi
# Copiar el archivo de vuelta a su ubicación
cp "$TEMP_DIR/$(basename "$ARCHIVO")" "$ARCHIVO"
# Limpiar
rm -rf "$TEMP_DIR"
echo "✅ Archivo '$ARCHIVO' recuperado exitosamente desde el commit $COMMIT_ID."
echo "Para confirmar estos cambios, usa:"
echo " git add \"$ARCHIVO\""
echo " git commit -m \"Recuperado $ARCHIVO desde el commit $COMMIT_ID\""
elif [ "$MODO" = "files" ]; then
# Obtener la lista de archivos que coinciden con el patrón en el commit
ARCHIVOS_COINCIDENTES=$(git ls-tree -r "$COMMIT_ID" --name-only | grep -E "$PATRON" || echo "")
if [ -z "$ARCHIVOS_COINCIDENTES" ]; then
echo "❌ No se encontraron archivos que coincidan con el patrón '$PATRON' en el commit $COMMIT_ID."
exit 1
fi
echo "Se encontraron $(echo "$ARCHIVOS_COINCIDENTES" | wc -l) archivos que coinciden con el patrón '$PATRON':"
echo "$ARCHIVOS_COINCIDENTES" | sed 's/^/ - /'
read -p "¿Quieres recuperar todos estos archivos? (s/n): " confirmacion
if [[ "$confirmacion" != "s" && "$confirmacion" != "S" ]]; then
echo "Operación cancelada por el usuario."
exit 0
fi
# Crear directorio temporal
TEMP_DIR=$(mktemp -d)
# Recuperar cada archivo
CONTADOR_EXITO=0
CONTADOR_ERROR=0
echo "$ARCHIVOS_COINCIDENTES" | while read -r archivo; do
# Crear la estructura de directorios necesaria
mkdir -p "$TEMP_DIR/$(dirname "$archivo")"
# Extraer el archivo del commit
git show "$COMMIT_ID:$archivo" > "$TEMP_DIR/$archivo" 2>/dev/null
if [ $? -eq 0 ]; then
# Crear directorio para el archivo si no existe
ARCHIVO_DIR=$(dirname "$archivo")
if [ "$ARCHIVO_DIR" != "." ] && [ ! -d "$ARCHIVO_DIR" ]; then
mkdir -p "$ARCHIVO_DIR"
fi
# Copiar el archivo de vuelta a su ubicación
cp "$TEMP_DIR/$archivo" "$archivo"
echo "✅ Recuperado: $archivo"
CONTADOR_EXITO=$((CONTADOR_EXITO + 1))
else
echo "❌ Error al recuperar: $archivo"
CONTADOR_ERROR=$((CONTADOR_ERROR + 1))
fi
done
# Limpiar
rm -rf "$TEMP_DIR"
echo "Recuperación finalizada: $CONTADOR_EXITO archivos recuperados, $CONTADOR_ERROR errores."
echo "Para confirmar estos cambios, usa:"
echo " git add -A"
echo " git commit -m \"Recuperados archivos $PATRON desde el commit $COMMIT_ID\""
fi
exit 0