Skip to content

Instantly share code, notes, and snippets.

@patriknyblad
Created June 16, 2023 11:51
Show Gist options
  • Save patriknyblad/4145652fd3a392a5feddb7e35d135123 to your computer and use it in GitHub Desktop.
Save patriknyblad/4145652fd3a392a5feddb7e35d135123 to your computer and use it in GitHub Desktop.
Squashes git history before a specified hash in a new branch and cherry picks all newer history
#!/bin/bash
# Specify the name of the branch you want to squash the history for
BRANCH_NAME=$1
# Specify the name of the new branch
NEW_BRANCH_NAME=$2
# Specify cutoff hash
CUTOFF_HASH=$3
# Find the initial commit hash
INITIAL_COMMIT_HASH=$(git log --reverse --pretty=format:"%H" | head -n 1)
# Confirm the operation
echo "This will create a new orphan branch '$NEW_BRANCH_NAME' with git history older than $CUTOFF_HASH squashed into a single commit."
read -p "Are you sure? (y/n): " CONFIRMATION
if [[ $CONFIRMATION != "y" ]]; then
echo "❌ Operation canceled."
exit 0
fi
# Checkout the branch we want to reduce the history for
git checkout $BRANCH_NAME
# Get all the commit hashes for original branch
commit_hashes=$(git log --pretty=format:"%h" --first-parent --reverse $CUTOFF_HASH..HEAD)
# Checkout the cutoff hash
git checkout $CUTOFF_HASH
# Reset git to initial commit soft
git reset --soft $INITIAL_COMMIT_HASH
# Create new orphan branch
git checkout --orphan $NEW_BRANCH_NAME
# Commit all the changes from initial commit to cutoff date as a single new commit
git commit -m "Squashed history older than $CUTOFF_HASH"
# Iterate over the commit hashes and apply them on the new branch
for commit_hash in $commit_hashes; do
# Perform actions with each commit hash
echo "πŸ’ Cherry picking commit: $commit_hash"
git cherry-pick "$commit_hash" -m 1
echo ""
echo ""
done
# Check diff to verify that the new branch matches the original branch
if git diff $BRANCH_NAME $NEW_BRANCH_NAME --quiet; then
echo "πŸŽ‰ New branch matches original branch."
else
echo "🟠 New branch does not match original branch."
git --no-pager diff $BRANCH_NAME $NEW_BRANCH_NAME --stat
fi
# Show stats
echo "πŸ“ˆ Number of commits in original branch: $(git rev-list --count $BRANCH_NAME)"
echo "πŸ“‰ Number of commits in new branch: $(git rev-list --count $NEW_BRANCH_NAME)"
echo "βœ… Done - New branch '$NEW_BRANCH_NAME' created with git history older than $CUTOFF_HASH squashed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment