npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

git-history-import

v0.3.0

Published

Export git history to JSON, edit it, import it back

Downloads

414

Readme

git-history-import

Export git history to JSON, edit it, import it back.

git-history-import wraps git fast-export and git fast-import to let you dump a repository's commit history into a plain JSON file, modify whatever you need in any text editor, then replay the changes back to rewrite the history.

npm package version number Actions Status License

Install

npm i -g git-history-import

Usage

Basic workflow:

# Export history to JSON
ghi export history.json

# Edit history.json with any editor...
# Change commit messages, author names, emails, dates, etc.

# Import modified history
ghi import history.json

All options:

# Export to stdout
ghi export

# Export specific range
ghi export history.json --range HEAD~5..HEAD

# Import without creating backup branch
ghi import history.json --no-backup

JSON Format

Each exported file looks like this:

{
  "version": 1,
  "repo": "/path/to/your/repo",
  "ref": "refs/heads/main",
  "exported_at": "2024-01-15T10:30:00.000Z",
  "commits": [
    {
      "original_hash": "a1b2c3d4e5f6...",
      "message": "fix: correct off-by-one error in parser",
      "author": {
        "name": "Jane Smith",
        "email": "[email protected]",
        "date": "2024-01-15 10:30:00 +0000"
      },
      "committer": {
        "name": "Jane Smith",
        "email": "[email protected]",
        "date": "2024-01-15 10:30:00 +0000"
      },
      "parents": ["9f8e7d6c5b4a..."]
    }
  ]
}

The date field uses human-readable format: YYYY-MM-DD HH:MM:SS +ZZZZ (e.g. 2024-01-15 10:30:00 +0200). Raw git format (1705312200 +0200) is also accepted during import.

What Can Be Modified

The following fields are rewritten during import:

  • message — commit message
  • author.name, author.email, author.date — authorship
  • committer.name, committer.email, committer.date — committer identity

The original_hash field is required for import. ghi matches each JSON entry to a commit in the repository by this hash and only patches commits that appear in the JSON. This means you can safely export a subset with --range, edit it, and import it back — only the matching commits are rewritten, and the rest of the history is preserved unchanged.

The order of entries in the commits array does not matter. You may also remove entries you don't want to edit. However, you must not add entries whose original_hash does not exist in the current branch.

The parents and ref fields are exported for reference only and are not used during import. The tree (file contents, including binary files) is preserved exactly as-is.

Backup and Recovery

By default, ghi import creates a backup branch named ghi-backup-<timestamp> pointing to the original HEAD before rewriting history.

To recover the original history:

# Check the backup branch name printed during import, then:
git checkout ghi-backup-<timestamp>

# Or reset your current branch back to the backup
git checkout main
git reset --hard ghi-backup-<timestamp>

Use --no-backup to skip creating the backup branch if you do not need it.

Completely Purging Old History

After importing, the old commits still exist as dangling objects in the object database. Git retains them in the reflog for approximately 90 days, so they can be recovered via git reflog. To remove all traces of the old history:

# 1. Delete backup branch
git branch -D ghi-backup-<timestamp>

# 2. Expire reflog
git reflog expire --expire=now --all

# 3. Garbage collect
git gc --prune=now --aggressive

# 4. Force push to remote
git push --force

# 5. All collaborators must re-clone

Warning: this is irreversible. Once garbage collected, the old commits cannot be recovered. If the repository has been pushed to a remote, any collaborator who already pulled the old history will still have it locally. They must delete their local clone and re-clone to avoid accidentally reintroducing old commits.

Programmatic API

git-history-import can also be used as a library:

import { exportHistory, importHistory, parseFastExport, patchFastExportStream } from "git-history-import";

// Export commits as a JSON string
const json = exportHistory({ range: "HEAD~5..HEAD" });

// Import from a file
importHistory("history.json", { noBackup: true });

Full TypeScript type definitions are included.

Limitations

  • Current branch only. ghi exports and imports the current branch. Detached HEAD is not supported.
  • original_hash is required. Every commit in the JSON must have an original_hash that exists in the current branch. Commits with missing or unknown hashes are rejected.
  • Scalability. The entire fast-export stream is buffered in memory. Very large repositories (hundreds of MB of history) may exceed the 100 MB buffer limit.

Development

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Lint and format
npm run lint
npm run lint:fix

Requirements

  • Node.js >= 20
  • git

License

MIT