scripts/sync_branches.sh
Rama master · réplica de lectura del repositorio original.
#!/bin/bash
set -euo pipefail
REMOTE_NAME=${1:-origin}
MASTER_BRANCH=${2:-master}
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "Error: scripts/sync_branches.sh must be run inside a git repository." >&2
exit 1
fi
if ! git remote | grep -qx "${REMOTE_NAME}"; then
echo "Error: remote '${REMOTE_NAME}' does not exist. Configure it before running this script." >&2
exit 2
fi
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "Fetching latest updates from ${REMOTE_NAME}..."
git fetch --prune "${REMOTE_NAME}"
if ! git show-ref --verify --quiet "refs/remotes/${REMOTE_NAME}/${MASTER_BRANCH}"; then
echo "Error: remote branch '${REMOTE_NAME}/${MASTER_BRANCH}' not found." >&2
exit 3
fi
mapfile -t REMOTE_BRANCHES < <(git for-each-ref --format='%(refname:strip=2)' "refs/remotes/${REMOTE_NAME}" | sort)
for REMOTE_BRANCH in "${REMOTE_BRANCHES[@]}"; do
BRANCH_NAME=${REMOTE_BRANCH#${REMOTE_NAME}/}
if [ "${BRANCH_NAME}" = "HEAD" ]; then
continue
fi
printf '\n=== Processing branch %s ===\n' "${BRANCH_NAME}"
if ! git show-ref --verify --quiet "refs/heads/${BRANCH_NAME}"; then
echo "Creating local branch ${BRANCH_NAME} tracking ${REMOTE_NAME}/${BRANCH_NAME}..."
git checkout -B "${BRANCH_NAME}" "${REMOTE_NAME}/${BRANCH_NAME}"
else
git checkout "${BRANCH_NAME}"
echo "Resetting ${BRANCH_NAME} to ${REMOTE_NAME}/${BRANCH_NAME}..."
git reset --hard "${REMOTE_NAME}/${BRANCH_NAME}"
fi
if [ "${BRANCH_NAME}" = "${MASTER_BRANCH}" ]; then
echo "Branch '${BRANCH_NAME}' is the master branch; skipping merge."
continue
fi
echo "Merging ${REMOTE_NAME}/${MASTER_BRANCH} into ${BRANCH_NAME}..."
if ! git merge --ff-only "${REMOTE_NAME}/${MASTER_BRANCH}"; then
echo "Fast-forward merge failed; attempting regular merge." >&2
if ! git merge "${REMOTE_NAME}/${MASTER_BRANCH}"; then
echo "Error: merge into '${BRANCH_NAME}' failed. Resolve conflicts manually before re-running." >&2
exit 4
fi
fi
done
if [ "${CURRENT_BRANCH}" != "$(git rev-parse --abbrev-ref HEAD)" ]; then
git checkout "${CURRENT_BRANCH}"
fi
printf '\nPushing synchronized branches to %s...\n' "${REMOTE_NAME}"
git push --all "${REMOTE_NAME}"
echo "Branch synchronization complete."