Building GitHub PR Squasher: A One-Click Solution for Clean Git History
Ever been asked to squash your commits in a Pull Request? If you're an open source contributor or a professional developer, chances are you've faced this situation multiple times. Today, I'm excited to share a tool I built that solves this common git workflow problem with just one click.
Ready to simplify your PR workflow?
One-click installation with Tampermonkey
The Problem
Many projects and organizations require a clean git history, often asking contributors to squash their multiple commits into a single, meaningful commit. While this is a great practice, it often involves:
- Learning complex git commands
- Potentially messing up the git history
- Time spent on manual operations
- Risk of losing commit information
- Extra back-and-forth in PR reviews
The Solution: GitHub PR Squasher
I created a browser userscript that adds a simple "Squash & Recreate PR" button to GitHub's PR interface. With one click, it:
- Creates a new branch
- Squashes all commits
- Creates a new PR with the squashed changes
- Preserves the original PR description
- Closes the original PR
- Cleans up by deleting the original branch
Key Features
- ✨ One-click operation
- 📝 Preserves PR context
- 🔒 Secure token storage
- 🏢 GitHub Enterprise support
- 🍴 Works with forked repositories
- 🌍 Supports both public and private repos
Technical Implementation
The script is built using JavaScript and the GitHub REST API. Here's how it works under the hood:
async function handleSquash() {
// Get PR details
const prDetails = await githubAPI(`/repos/${owner}/${repo}/pulls/${prNumber}`);
// Create new branch with base commit
await githubAPI(`/repos/${owner}/${repo}/git/refs`, 'POST', {
ref: `refs/heads/${newBranchName}`,
sha: prDetails.base.sha
});
// Create squashed commit
const newCommit = await githubAPI(`/repos/${owner}/${repo}/git/commits`, 'POST', {
message: `${prInfo.title}\n\nSquashed commits from #${prInfo.prNumber}`,
tree: headCommit.tree.sha,
parents: [prDetails.base.sha]
});
// Create new PR with squashed changes
const newPR = await githubAPI(`/repos/${owner}/${repo}/pulls`, 'POST', {
title: `${prInfo.title} (Squashed)`,
head: newBranchName,
base: prInfo.baseBranch,
body: `${prInfo.description}\n\n---\n_Squashed version of #${prInfo.prNumber}_`
});
}
Installation and Setup
- Install from Greasy Fork
- Set up your GitHub token
- Start squashing PRs with one click!
Real-World Impact
This tool is particularly valuable for:
Open Source Contributors
- No need to learn complex git commands
- Quickly comply with project requirements
- Focus on code instead of git operations
Professional Developers
- Maintain clean git history effortlessly
- Save time in PR reviews
- Reduce manual errors
Team Leads
- Enforce consistent commit history
- Simplify code review process
- Reduce onboarding friction
The Development Process
Building this tool taught me several valuable lessons:
- API Integration: Working with GitHub's REST API
- User Experience: Making complex operations simple
- Error Handling: Dealing with various edge cases
- Enterprise Support: Supporting different GitHub environments
Future Enhancements
I'm planning to add:
- Custom commit message templates
- Batch PR processing
- More configuration options
- Statistics tracking
Get Involved
The project is open source and available on GitHub:
Feel free to contribute, report issues, or suggest improvements!
Conclusion
What started as a solution to a personal pain point has evolved into a tool that can help developers across the globe maintain cleaner git histories with less effort. Whether you're an open source contributor or a professional developer, GitHub PR Squasher can save you time and reduce friction in your development workflow.
Give it a try and let me know what you think!
This post was written by Balakumar, a developer passionate about creating tools that make developers' lives easier. Follow me for more developer tools and insights.