Git Squash to Single Commit
Create a fresh repository with a single commit, preserving current state
Metadata
- Author: Wei
- Version: 1.0.0
- Dependencies: git
This will completely remove all Git history!
Code
bash
#!/bin/bash
# @title Git Squash to Single Commit
# @description Create a fresh repository with a single commit, preserving current state
# @author Wei
# @version 1.0.0
#
# This script creates a completely new Git history with just one commit containing
# all current files. This is useful when you want to start fresh without any history.
#
# @example
# Usage:
# ./git-squash-to-single-commit.sh [commit-message]
# ./git-squash-to-single-commit.sh "Initial commit"
#
# @requires git
# @note This will completely remove all Git history!
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
NEW_AUTHOR_NAME="Wei Guo"
NEW_AUTHOR_EMAIL="[email protected]"
DEFAULT_MESSAGE="Initial commit - consolidated history"
# Function to print colored messages
print_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_step() {
echo -e "${BLUE}[STEP]${NC} $1"
}
# Get commit message from argument or use default
COMMIT_MESSAGE="${1:-$DEFAULT_MESSAGE}"
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
print_error "Not a git repository"
exit 1
fi
# Check if there are uncommitted changes
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
print_error "You have uncommitted changes. Please commit or stash them first."
exit 1
fi
# Get current branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
print_info "Current branch: $CURRENT_BRANCH"
echo ""
print_warning "This will:"
echo " 1. Delete ALL Git history"
echo " 2. Create a single new commit with all current files"
echo " 3. Use author: $NEW_AUTHOR_NAME <$NEW_AUTHOR_EMAIL>"
echo " 4. Commit message: $COMMIT_MESSAGE"
echo ""
print_warning "This operation CANNOT be easily undone!"
echo ""
# Ask for confirmation
read -p "Are you sure you want to continue? (yes/no): " -r
echo
if [[ ! $REPLY =~ ^[Yy][Ee][Ss]$ ]]; then
print_info "Operation cancelled"
exit 0
fi
# Create backup branch
BACKUP_BRANCH="backup-before-squash-$(date +%Y%m%d-%H%M%S)"
print_step "Creating backup branch: $BACKUP_BRANCH"
git branch "$BACKUP_BRANCH"
print_info "Backup created at: $BACKUP_BRANCH"
# Store the current tree
print_step "Saving current state..."
TREE=$(git write-tree)
# Create a new commit with the current tree
print_step "Creating new commit..."
export GIT_AUTHOR_NAME="$NEW_AUTHOR_NAME"
export GIT_AUTHOR_EMAIL="$NEW_AUTHOR_EMAIL"
export GIT_COMMITTER_NAME="$NEW_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$NEW_AUTHOR_EMAIL"
NEW_COMMIT=$(git commit-tree "$TREE" -m "$COMMIT_MESSAGE")
# Reset current branch to the new commit
print_step "Resetting branch to new commit..."
git reset --hard "$NEW_COMMIT"
# Clean up
unset GIT_AUTHOR_NAME
unset GIT_AUTHOR_EMAIL
unset GIT_COMMITTER_NAME
unset GIT_COMMITTER_EMAIL
echo ""
print_info "Successfully created fresh history!"
echo ""
print_step "New commit details:"
git log --format=fuller -1
echo ""
print_warning "Next steps:"
echo " 1. Review the changes: git log"
echo " 2. If satisfied, force push: git push --force-with-lease"
echo " 3. If you need to undo, restore backup: git reset --hard $BACKUP_BRANCH"
echo " 4. Delete backup branch when done: git branch -D $BACKUP_BRANCH"
echo ""
exit 0File Information
- Filename:
git-squash-to-single-commit.sh - Category: git
- Language: BASH