Files
fn_registry/bash/functions/shell/git_push_all_remotes.sh
T
egutierrez 8f45b40528 feat: add bash shell utility functions
12 funciones Bash del dominio shell: utilidades de scripting (bash_log,
bash_colors, bash_check_deps, bash_confirm, bash_handle_error, bash_safe_run),
manipulacion de texto (convert_text_case), estructura de proyectos
(create_project_structure), y operaciones git (git_clean_branches,
git_log_visual, git_push_all_remotes, git_repo_status). Cada una con su
.sh y .md de frontmatter.
2026-04-12 13:54:15 +02:00

128 lines
3.6 KiB
Bash

#!/usr/bin/env bash
# git_push_all_remotes
# --------------------
# Hace commit de todos los cambios pendientes (si los hay) y pushea
# a todos los remotes configurados en el repositorio.
#
# USO:
# source git_push_all_remotes.sh
# git_push_all_remotes [--message "mensaje"]
#
# ARGUMENTOS:
# --message "msg" Mensaje de commit (si hay cambios). Si se omite y hay
# cambios, sale con error.
git_push_all_remotes() {
local commit_msg=""
# Parsear argumentos
while [[ $# -gt 0 ]]; do
case "$1" in
--message|-m)
commit_msg="$2"
shift 2
;;
*)
shift
;;
esac
done
# Validar repo
if ! git rev-parse --is-inside-work-tree &>/dev/null; then
echo "git_push_all_remotes: el directorio actual no es un repositorio Git" >&2
return 1
fi
local branch
branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null)"
local remotes
remotes="$(git remote 2>/dev/null || true)"
if [[ -z "$remotes" ]]; then
echo "git_push_all_remotes: no hay remotes configurados en este repositorio" >&2
return 1
fi
echo "Rama actual: ${branch}"
echo "Remotes:"
echo "$remotes" | while IFS= read -r r; do
local url
url="$(git remote get-url "$r" 2>/dev/null || echo "?")"
echo " ${r}${url}"
done
echo ""
# Gestión del commit si hay cambios
local has_changes=false
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
has_changes=true
fi
if [[ "$has_changes" == true ]]; then
if [[ -z "$commit_msg" ]]; then
echo "git_push_all_remotes: hay cambios pero no se proporcionó --message" >&2
echo " Usa: git_push_all_remotes --message \"tu mensaje\"" >&2
return 1
fi
echo "Cambios detectados:"
git status --short | while IFS= read -r line; do
echo " ${line}"
done
echo ""
echo "Añadiendo todos los cambios..."
git add -A
echo "Haciendo commit: \"${commit_msg}\""
git commit -m "$commit_msg"
echo ""
else
echo "Directorio de trabajo limpio. Se empujarán commits existentes."
echo ""
fi
# Push a cada remote
local ok_count=0
local fail_count=0
local failed_remotes=()
local remote_count
remote_count="$(echo "$remotes" | wc -l | tr -d ' ')"
while IFS= read -r remote; do
# Verificar si la rama existe en el remote
local push_flags=""
if ! git ls-remote --heads "$remote" "$branch" 2>/dev/null | grep -q "$branch"; then
push_flags="--set-upstream"
echo "La rama '${branch}' no existe en '${remote}', se creará"
fi
echo "Push → ${remote} (${branch})..."
# shellcheck disable=SC2086
if git push $push_flags "$remote" "$branch" 2>&1; then
echo " Push completado → ${remote}/${branch}"
ok_count=$((ok_count + 1))
else
echo " Falló el push a ${remote}/${branch}" >&2
fail_count=$((fail_count + 1))
failed_remotes+=("$remote")
fi
echo ""
done <<< "$remotes"
echo "=== Resumen ==="
echo "Push completado en ${ok_count}/${remote_count} remote(s)"
if [[ $fail_count -gt 0 ]]; then
echo "Fallaron ${fail_count} remote(s): ${failed_remotes[*]}" >&2
return 1
fi
}
# Ejecutar si se invoca directamente
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
git_push_all_remotes "$@"
fi