Commit automático por git subir

This commit is contained in:
2025-08-16 22:16:10 -03:00
parent 68ea6dc88f
commit f05e3d20c5
4 changed files with 184 additions and 207 deletions

150
README.md
View File

@ -1,119 +1,99 @@
# 🚀 git subir # 🚀 git-subir
Comando personalizado para automatizar el push de cambios a un repositorio Gitea. Incluye autenticación segura, commits interactivos, resolución de conflictos y configuración automatizada. Script CLI para automatizar el push de cambios a repositorios Gitea con autenticación segura, configuración automática de remotos, commits interactivos, recuperación ante errores y cifrado opcional de credenciales.
--- ---
## 📂 Archivos incluidos ## 📦 Archivos incluidos
### `instalar-subir.sh` | Archivo | Descripción |
Script de instalación que: |------------------------|-----------------------------------------------------------------------------|
| `instalar-subir.sh` | Instalador interactivo que configura credenciales, instala el comando global `git-subir` y valida entorno. |
- Verifica si `openssl` está instalado (y lo instala si falta). | `git-subir` | Script principal que automatiza el flujo de push, commits, configuración de remotos y recuperación ante errores. |
- Solicita credenciales de Gitea: usuario, token/contraseña y URL base de la API. | `desinstalar-subir.sh` | Elimina el binario instalado y la configuración/credenciales guardadas. |
- Verifica las credenciales contra la API de Gitea.
- Permite guardar las credenciales cifradas con `openssl` o en texto plano.
- Crea el script principal `git-subir.sh` en `~/.scripts/`.
- Genera un alias global `git subir` disponible en todo el sistema.
### `git-subir.sh`
Script principal que:
- Carga las credenciales (descifrándolas si están cifradas).
- Detecta cambios sin commitear y ofrece hacer commit automático.
- Realiza `git push` con autenticación embebida.
- Si el push falla, intenta `git pull --allow-unrelated-histories`.
- Detecta conflictos y ofrece hacer merge automático.
- Muestra mensajes claros y estructurados para guiar al usuario.
### `desinstalar-subir.sh`
Script de desinstalación que:
- Elimina el alias global `git subir`.
- Borra el script `git-subir.sh`.
- Elimina las credenciales guardadas (cifradas o no).
--- ---
## 🔐 Seguridad ## 🔧 Requisitos
- Las credenciales pueden guardarse cifradas con `openssl` usando una contraseña definida por el usuario. - Bash 4+
- El script `git-subir.sh` descifra las credenciales en tiempo de ejecución y las borra inmediatamente después de usarlas. - Git instalado y configurado
- Si se elige guardar sin cifrar, se almacenan en `~/.scripts/.env` con permisos restringidos (`chmod 600`). - `curl`, `jq`, `openssl` disponibles en el sistema
- Acceso a un servidor Gitea con token o usuario/contraseña válidos
--- - Carpeta `~/.local/bin` incluida en el `$PATH`
## 📦 Requisitos
- `openssl` (se instala automáticamente si falta)
- Acceso a una instancia de Gitea con API habilitada
- Permisos de escritura en `/usr/local/bin` para crear el alias global
--- ---
## 🧪 Instalación ## 🧪 Instalación
```bash ```bash
chmod +x desinstalar-subir.sh chmod +x instalar-subir.sh
./instalar-subir.sh ./instalar-subir.sh
Durante la instalación se te pedirá: Durante la instalación se te pedirá:
Usuario de Gitea URL base del servidor Gitea (ej: https://gitea.midominio.com)
Token o contraseña Usuario y contraseña o token
URL base de la API (ej: https://gitea.midominio.org) Si querés cifrar las credenciales (usando AES-256-CBC con PBKDF2)
Si querés guardar las credenciales cifradas Confirmación para instalar git-subir como comando global
Al finalizar, podrás usar el comando: El script valida las credenciales contra la API de Gitea antes de continuar.
🚀 Uso
Una vez instalado, podés usar git-subir desde cualquier repositorio git:
bash bash
git subir git-subir
El script realiza:
Carga y descifrado de credenciales (si están cifradas)
Verificación de cambios sin commitear
Commit automático si lo autorizás
Verificación de configuración del remote origin
Push al repositorio remoto
Si el push falla, intenta git pull --rebase y reintenta
🔁 Reconfigurar credenciales
Podés ejecutar:
bash
git-subir --reconfigurar
Esto permite:
Cambiar usuario/contraseña o token
Elegir si querés cifrar o guardar en texto plano
Validar nuevamente contra la API
Reescribir la configuración en ~/.config/git-subir/
🔐 Seguridad
Cifrado con openssl usando AES-256-CBC y derivación PBKDF2
La contraseña de cifrado nunca se guarda
Los archivos se almacenan en ~/.config/git-subir/ para mantener orden
El binario se instala en ~/.local/bin/git-subir para uso global
🧹 Desinstalación 🧹 Desinstalación
bash bash
chmod +x ./desinstalar-subir.sh chmod +x desinstalar-subir.sh
./desinstalar-subir.sh ./desinstalar-subir.sh
Esto elimina: Esto elimina:
El alias git subir El binario git-subir de ~/.local/bin
El script git-subir.sh Las credenciales y configuración de ~/.config/git-subir
Las credenciales guardadas
🔄 Flujo de uso
Ejecutás git subir.
El script carga las credenciales (descifradas si están cifradas).
Detecta si hay cambios sin commitear:
Si hay, ofrece hacer commit automático.
Intenta hacer git push al repositorio remoto con autenticación embebida.
Si el push falla:
Intenta git pull --allow-unrelated-histories.
Si hay conflictos, los muestra y ofrece hacer merge automático.
Si todo sale bien, muestra 🎉 Push completado.
💡 Ejemplo de uso
bash
git subir
Si hay cambios sin commitear, te preguntará si querés hacer commit.
Si hay conflictos, te preguntará si querés hacer merge automático.
Si todo está limpio, sube los cambios directamente.
🧠 Autor 🧠 Autor
Nahuel Baglietto Scripts diseñados para mejorar la experiencia de trabajo con Git y Gitea, priorizando seguridad, automatización y facilidad de uso. Nahuel Baglietto
🛡️ Licencia
Este proyecto puede ser usado, modificado y distribuido libremente bajo los términos que defina su autor.

1
credenciales.enc Normal file
View File

@ -0,0 +1 @@
Salted__<EFBFBD><06> <0C><>|R<><52>R<EFBFBD><4A>7"<22>

View File

@ -1,11 +1,11 @@
#!/bin/bash #!/bin/bash
set -e
echo "🧹 Desinstalando git subir..." echo "🧹 Desinstalando git subir..."
sudo rm -f /usr/local/bin/git-subir # Eliminar binario
rm -f "$HOME/.scripts/git-subir.sh" rm -f "$HOME/.local/bin/git-subir"
rm -f "$HOME/.scripts/.env"
rm -f "$HOME/.scripts/.env.enc" # Eliminar credenciales y config
rm -rf "$HOME/.config/git-subir"
echo "✅ Desinstalación completa." echo "✅ Desinstalación completa."

View File

@ -1,147 +1,143 @@
#!/bin/bash #!/bin/bash
set -e
echo "🔧 Instalación del comando git subir" echo "🚀 Instalando comando git subir..."
# 📦 Verificar openssl # Solicitar datos
if ! command -v openssl &> /dev/null; then read -p "👤 Usuario de Gitea: " USUARIO
echo "⚠️ openssl no está instalado. Instalando..." read -s -p "🔑 Token o contraseña: " TOKEN
if command -v apt &> /dev/null; then
sudo apt update && sudo apt install -y openssl
elif command -v pacman &> /dev/null; then
sudo pacman -Sy --noconfirm openssl
else
echo "❌ No se pudo instalar openssl automáticamente. Instalalo manualmente."
exit 1
fi
fi
# 📁 Crear carpeta
mkdir -p "$HOME/.scripts"
# 🔄 Reconfigurar si existen credenciales
if [[ -f "$HOME/.scripts/.env" || -f "$HOME/.scripts/.env.enc" ]]; then
read -p "⚠️ Ya existen credenciales. ¿Querés reconfigurarlas? (s/n): " reconfig
[[ "$reconfig" != "s" ]] && echo "🚫 Instalación cancelada." && exit 0
fi
# 🔐 Solicitar credenciales
read -p "👤 Usuario de Gitea: " GITEA_USER
read -s -p "🔑 Token o contraseña: " GITEA_TOKEN
echo "" echo ""
read -p "🌐 URL base de la API de Gitea (ej: https://gitea.midominio.org): " GITEA_API_URL read -p "🌐 URL base de la API de Gitea: " API_BASE
# 🔎 Verificar credenciales # Verificar credenciales antes de cifrar
response=$(curl -s -u "$GITEA_USER:$GITEA_TOKEN" "$GITEA_API_URL/api/v1/user") ENDPOINTS=("$API_BASE/user" "$API_BASE/api/v1/user")
if ! echo "$response" | grep -q '"login":"'"$GITEA_USER"'"'; then ENDPOINT_VALIDO=""
echo "❌ Credenciales inválidas. Abortando instalación." for URL in "${ENDPOINTS[@]}"; do
exit 1 RESP=$(curl -s -o /dev/null -w "%{http_code}" -u "$USUARIO:$TOKEN" "$URL")
echo "🔍 Probando $URL → Código: $RESP"
if [ "$RESP" == "200" ]; then
ENDPOINT_VALIDO="$URL"
break
fi
done
if [ -z "$ENDPOINT_VALIDO" ]; then
echo "❌ Error de autenticación. No se encontró endpoint válido."
exit 1
fi fi
# 🔐 Cifrar si desea echo "✅ Autenticación exitosa con $ENDPOINT_VALIDO"
read -p "¿Querés guardar las credenciales cifradas con openssl? (s/n): " cifrar
if [[ "$cifrar" == "s" ]]; then # Crear carpeta segura
echo "🔐 Ingresá una contraseña para cifrar:" CONFIG_DIR="$HOME/.config/git-subir"
read -s passphrase mkdir -p "$CONFIG_DIR"
echo -e "GITEA_USER=$GITEA_USER\nGITEA_TOKEN=$GITEA_TOKEN\nGITEA_API_URL=$GITEA_API_URL" | \
openssl enc -aes-256-cbc -pbkdf2 -salt -out "$HOME/.scripts/.env.enc" -pass pass:"$passphrase" # Preguntar si desea cifrar
rm -f "$HOME/.scripts/.env" read -p "🔐 ¿Querés cifrar las credenciales? (s/n): " CIFRAR
echo "✅ Credenciales cifradas guardadas." if [[ "$CIFRAR" == "s" ]]; then
read -s -p "🔑 Contraseña para cifrado: " CLAVE
echo ""
echo "$USUARIO:$TOKEN:$API_BASE" | openssl enc -aes-256-cbc -pbkdf2 -salt -out "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE"
else else
echo -e "GITEA_USER=$GITEA_USER\nGITEA_TOKEN=$GITEA_TOKEN\nGITEA_API_URL=$GITEA_API_URL" > "$HOME/.scripts/.env" echo "$USUARIO:$TOKEN:$API_BASE" > "$CONFIG_DIR/credenciales.txt"
chmod 600 "$HOME/.scripts/.env"
rm -f "$HOME/.scripts/.env.enc"
echo "⚠️ Credenciales guardadas sin cifrar."
fi fi
# 📜 Script principal # Crear script git-subir
cat <<'EOF' > "$HOME/.scripts/git-subir.sh" cat > "$CONFIG_DIR/git-subir" <<'EOF'
#!/bin/bash #!/bin/bash
set -e
CONFIG_DIR="$HOME/.config/git-subir"
# 🔐 Cargar credenciales # 🔐 Cargar credenciales
if [[ -f "$HOME/.scripts/.env.enc" ]]; then if [ -f "$CONFIG_DIR/credenciales.enc" ]; then
echo "🔐 Ingresá la contraseña para descifrar tus credenciales:" read -s -p "🔑 Ingresá la contraseña de cifrado: " CLAVE
read -s passphrase echo ""
openssl enc -aes-256-cbc -pbkdf2 -d -in "$HOME/.scripts/.env.enc" -pass pass:"$passphrase" > /tmp/.env.dec CREDS=$(openssl enc -aes-256-cbc -pbkdf2 -d -in "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE" 2>/dev/null)
source /tmp/.env.dec if [ -z "$CREDS" ]; then
rm /tmp/.env.dec echo "❌ Error al descifrar credenciales."
elif [[ -f "$HOME/.scripts/.env" ]]; then
source "$HOME/.scripts/.env"
else
echo "❌ No se encontraron credenciales. Ejecutá instalar-subir.sh primero."
exit 1 exit 1
fi
else
CREDS=$(cat "$CONFIG_DIR/credenciales.txt")
fi fi
# 📍 Verificar si estamos en un repositorio Git USUARIO=$(echo "$CREDS" | cut -d: -f1)
if ! git rev-parse --is-inside-work-tree &> /dev/null; then TOKEN=$(echo "$CREDS" | cut -d: -f2)
echo "📁 Este directorio no es un repositorio Git." API_BASE=$(echo "$CREDS" | cut -d: -f3)
read -p "¿Querés inicializarlo ahora? (s/n): " init_repo
if [[ "$init_repo" == "s" ]]; then # 🔁 Reconfigurar credenciales
git init if [[ "$1" == "--reconfigurar" ]]; then
read -p "📦 Ingresá el nombre del repositorio remoto (ej: git-operaciones.git): " repo_nombre read -p "👤 Nuevo usuario: " USUARIO
remote_url="$GITEA_API_URL/$GITEA_USER/$repo_nombre" read -s -p "🔑 Nuevo token: " TOKEN
git remote add origin "$remote_url" echo ""
echo "✅ Repositorio inicializado y remoto configurado: $remote_url" read -p "🌐 Nueva URL base: " API_BASE
else read -p "🔐 ¿Cifrar credenciales? (s/n): " CIFRAR
echo "🚫 Operación cancelada. Ejecutá desde un repositorio Git válido." if [[ "$CIFRAR" == "s" ]]; then
exit 1 read -s -p "🔑 Contraseña para cifrado: " CLAVE
fi echo ""
echo "$USUARIO:$TOKEN:$API_BASE" | openssl enc -aes-256-cbc -pbkdf2 -salt -out "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE"
rm -f "$CONFIG_DIR/credenciales.txt"
else
echo "$USUARIO:$TOKEN:$API_BASE" > "$CONFIG_DIR/credenciales.txt"
rm -f "$CONFIG_DIR/credenciales.enc"
fi
echo "✅ Credenciales reconfiguradas."
exit 0
fi fi
remote_url=$(git remote get-url origin | sed 's|https://||') # 📂 Verificar si estamos en un repo
auth_url="https://$GITEA_USER:$GITEA_TOKEN@$remote_url" git rev-parse --is-inside-work-tree &>/dev/null || {
echo "❌ No estás en un repositorio Git."
exit 1
}
function marco() { # 🧼 Detectar si el repo está vacío
echo -e "╔════════════════════════════════╗" git rev-parse HEAD &>/dev/null
echo -e "║ $1" if [ $? -ne 0 ]; then
echo -e "╚════════════════════════════════╝" echo "📁 El repositorio está vacío."
read -p "¿Querés crear README.md inicial? (s/n): " RESP
if [[ "$RESP" == "s" ]]; then
touch README.md
git add README.md
git commit -m "Commit inicial por git subir"
fi
fi
# 🌐 Verificar remote origin
git remote -v | grep origin >/dev/null || {
read -p "🌐 No hay remote origin. Ingresá URL del remote: " REMOTE
git remote add origin "$REMOTE"
} }
# 📦 Detectar cambios sin commitear # 📦 Detectar cambios sin commitear
if ! git diff-index --quiet HEAD; then if ! git diff-index --quiet HEAD --; then
echo "📦 Se detectaron cambios sin commitear:" echo "📦 Hay cambios sin commitear."
git status -s read -p "¿Querés hacer commit automático? (s/n): " RESP
read -p "¿Querés hacer commit automático de estos cambios? (s/n): " auto_commit if [[ "$RESP" == "s" ]]; then
if [[ "$auto_commit" == "s" ]]; then git add .
read -p "📝 Ingresá el mensaje de commit: " mensaje git commit -m "Commit automático por git subir"
git add . fi
git commit -m "$mensaje"
echo "✅ Commit realizado."
fi
fi fi
# 🚀 Intentar push # 🚀 Intentar push
echo "🚀 Subiendo archivos al repositorio remoto..." echo "🚀 Ejecutando git push..."
if ! git push "$auth_url"; then git push
echo "⚠️ Push fallido. Intentando pull con --allow-unrelated-histories..." if [ $? -ne 0 ]; then
git pull "$auth_url" --allow-unrelated-histories || true echo "⚠️ Push falló. Intentando git pull y reintento..."
git pull --rebase
conflictos=$(git diff --name-only --diff-filter=U) git push
if [[ -n "$conflictos" ]]; then
echo "🚨 Conflictos detectados:"
echo "$conflictos"
read -p "¿Hacer merge automático? (s/n): " merge_auto
if [[ "$merge_auto" == "s" ]]; then
git add .
git commit -m "🔀 Merge automático"
else
echo "❌ Merge cancelado. Resolvé los conflictos manualmente."
exit 1
fi
fi
git push "$auth_url"
fi fi
echo "🎉 Push completado."
EOF EOF
chmod +x "$HOME/.scripts/git-subir.sh" chmod +x "$CONFIG_DIR/git-subir"
# 🔗 Alias global # Instalar en ~/.local/bin
echo "Creando alias git-subir..." mkdir -p "$HOME/.local/bin"
echo -e "#!/bin/bash\nexec \"$HOME/.scripts/git-subir.sh\" \"\$@\"" | sudo tee /usr/local/bin/git-subir > /dev/null cp "$CONFIG_DIR/git-subir" "$HOME/.local/bin/git-subir"
sudo chmod +x /usr/local/bin/git-subir chmod +x "$HOME/.local/bin/git-subir"
echo "✅ Instalación completa. Usá el comando: git subir" # Asegurar que ~/.local/bin esté en PATH
SHELL_RC="$HOME/.bashrc"
[[ "$SHELL" == */zsh ]] && SHELL_RC="$HOME/.zshrc"
grep -q 'export PATH="$HOME/.local/bin:$PATH"' "$SHELL_RC" || echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$SHELL_RC"
echo "✅ Instalación completa. Usá 'git subir' desde cualquier repositorio."