Created
September 27, 2025 17:04
-
-
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!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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