Skip to content

Instantly share code, notes, and snippets.

@carlosjhr64
Created September 27, 2025 17:04
Show Gist options
  • Select an option

  • Save carlosjhr64/1af16f6cb7af52472c83b459807e9633 to your computer and use it in GitHub Desktop.

Select an option

Save carlosjhr64/1af16f6cb7af52472c83b459807e9633 to your computer and use it in GitHub Desktop.
Script to reset and force-push a Git branch... Delete All Past Commits in a Git Branch!
#!/bin/bash
# Developed with help from Grok by xAI.
# Prompt user for Git directory
read -p "Enter the Git repository directory (e.g., $HOME/.cfg): " GIT_DIR
# Validate directory exists and is a Git repo
if [ ! -d "$GIT_DIR" ] || ! git --git-dir="$GIT_DIR" rev-parse --git-dir >/dev/null 2>&1; then
echo "Error: '$GIT_DIR' is not a valid Git repository directory."
exit 1
fi
# Set work tree to parent directory of GIT_DIR
WORK_TREE="$(dirname "$GIT_DIR")"
# Check write permissions for GIT_DIR
if [ ! -w "$GIT_DIR" ]; then
echo "Error: No write permissions for '$GIT_DIR'."
exit 1
fi
# Check write permissions for WORK_TREE
if [ ! -w "$WORK_TREE" ]; then
echo "Error: No write permissions for '$WORK_TREE'."
exit 1
fi
# Check for uncommitted changes
if [ -n "$(git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" status --porcelain)" ]; then
echo "Error: Uncommitted changes detected. Please commit or stash changes before proceeding."
exit 1
fi
# Prompt for branch name (default: main)
read -p "Enter the branch name to reset (default: main): " BRANCH_NAME
BRANCH_NAME=${BRANCH_NAME:-main}
# Verify branch exists
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then
echo "Error: Branch '$BRANCH_NAME' does not exist."
exit 1
fi
# Check for origin remote
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" remote | grep -q origin; then
echo "Error: No 'origin' remote found."
exit 1
fi
# Create backup of GIT_DIR in WORK_TREE
BACKUP_DIR="$WORK_TREE/.git-backup-$(date +%Y%m%d_%H%M%S)"
echo "Creating backup of '$GIT_DIR' at '$BACKUP_DIR'"
cp -r "$GIT_DIR" "$BACKUP_DIR"
if [ $? -ne 0 ]; then
echo "Error: Failed to create backup of '$GIT_DIR'."
exit 1
fi
# Prompt to skip aggressive garbage collection
read -p "Run aggressive garbage collection? This may be slow for large repos (y/N): " GC_CONFIRM
GC_CONFIRM=${GC_CONFIRM:-N}
# Warn about force-push consequences
echo "WARNING: This will force-push to origin/$BRANCH_NAME, overwriting remote history."
echo "Backup created at '$BACKUP_DIR'. To restore, replace '$GIT_DIR' with '$BACKUP_DIR'."
read -p "Continue with force-push? (y/N): " CONFIRM
if [ "$CONFIRM" != "y" ] && [ "$CONFIRM" != "Y" ]; then
echo "Operation cancelled."
exit 1
fi
# Ensure on specified branch
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" checkout "$BRANCH_NAME" >/dev/null 2>&1; then
echo "Error: Failed to checkout branch '$BRANCH_NAME'."
exit 1
fi
# Stage only tracked files
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" ls-files -z | xargs -0 git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" add; then
echo "Error: Failed to stage tracked files."
exit 1
fi
# Create orphan branch
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" checkout --orphan "new-$BRANCH_NAME" >/dev/null 2>&1; then
echo "Error: Failed to create orphan branch."
exit 1
fi
# Commit staged files, bypassing pre-commit hooks
echo "Bypassing pre-commit hooks with --no-verify"
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" commit -n -m "Initial commit"; then
echo "Error: Failed to commit staged files."
git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" status
exit 1
fi
# Delete old branch
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" branch -D "$BRANCH_NAME" >/dev/null 2>&1; then
echo "Error: Failed to delete old branch '$BRANCH_NAME'."
exit 1
fi
# Rename new branch
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" branch -m "$BRANCH_NAME" >/dev/null 2>&1; then
echo "Error: Failed to rename branch to '$BRANCH_NAME'."
exit 1
fi
# Clean repository (optional)
if [ "$GC_CONFIRM" = "y" ] || [ "$GC_CONFIRM" = "Y" ]; then
echo "Running aggressive garbage collection..."
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" gc --aggressive --prune=all >/dev/null 2>&1; then
echo "Warning: Garbage collection failed, but proceeding with push."
fi
fi
# Update refs
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" update-ref "refs/heads/$BRANCH_NAME" HEAD >/dev/null 2>&1; then
echo "Error: Failed to update refs for '$BRANCH_NAME'."
exit 1
fi
# Force-push to remote
if ! git --git-dir="$GIT_DIR" --work-tree="$WORK_TREE" push --set-upstream origin "$BRANCH_NAME" --force >/dev/null 2>&1; then
echo "Error: Failed to force-push to origin/$BRANCH_NAME."
exit 1
fi
echo "Branch '$BRANCH_NAME' reset and force-pushed successfully."
echo "Backup available at '$BACKUP_DIR' for restoration if needed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment