git-safe-sync.sh 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. BASE_BRANCH="${1:-main}"
  4. if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  5. echo "Not a git repository"
  6. exit 1
  7. fi
  8. CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
  9. if [ "$CURRENT_BRANCH" = "HEAD" ]; then
  10. echo "Detached HEAD is not supported by this script"
  11. exit 1
  12. fi
  13. if [ "$CURRENT_BRANCH" = "$BASE_BRANCH" ]; then
  14. echo "Refusing to run on base branch: $BASE_BRANCH"
  15. echo "Please switch to a feature/fix branch first."
  16. exit 1
  17. fi
  18. if [ -n "$(git status --porcelain)" ]; then
  19. STASH_NAME="$(date +%F)-${CURRENT_BRANCH}-safe-sync"
  20. echo "Working tree is dirty, stashing as: ${STASH_NAME}"
  21. git stash push -u -m "$STASH_NAME" >/dev/null
  22. STASHED=1
  23. else
  24. STASHED=0
  25. fi
  26. echo "Fetching latest refs..."
  27. git fetch origin --prune
  28. echo "Rebasing ${CURRENT_BRANCH} onto origin/${BASE_BRANCH}..."
  29. git rebase "origin/${BASE_BRANCH}"
  30. if [ "$STASHED" -eq 1 ]; then
  31. echo "Restoring stashed changes..."
  32. git stash pop || {
  33. echo "stash pop has conflicts; resolve manually, then continue."
  34. exit 2
  35. }
  36. fi
  37. echo "Safe sync done."