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-detect-case-change

v1.2.0

Published

Detect file name case changes in a Git repository

Readme

git-detect-case-change

Detect and fix case-only filename changes that Git can't see on macOS/Windows.

On case-insensitive filesystems, renaming utils.tsUtils.ts won't register in Git. This tool detects those mismatches and fixes them.

# Renamed foo.js → Foo.js but Git didn't notice?
npx git-detect-case-change              # Stage the case rename in Git
npx git-detect-case-change --fix-local  # Rename local files to match Git

Support this project by ⭐️ starring and sharing it. Follow me to see what other projects I'm working on.

Usage

The tool works in two directions depending on which casing is correct:

  • Local is the source of truth — you renamed files locally and Git needs to know
  • Git is the source of truth — a teammate renamed files and your filesystem needs to catch up

| Scenario | Command | Effect | | ----------------------------- | ---------------------------------------- | --------------------------------- | | Local is the source of truth | npx git-detect-case-change | Stages the rename with git mv | | Git is the source of truth | npx git-detect-case-change --fix-local | Renames local files to Git's case |

Example output:

$ npx git-detect-case-change
src/utils.ts -> src/Utils.ts
lib/helper.js -> lib/Helper.js

When to use it

  • Bundlers (Vite/Webpack/Rollup) error due to mismatched import casing
  • CI fails on Linux but your Mac build passes
  • Git doesn't show a rename even though you changed the file
  • Teammate pushed case-only changes and your local filesystem is out of sync

Options

Dry run

Preview changes without modifying anything:

npx git-detect-case-change --dry
npx git-detect-case-change --fix-local --dry

Check mode

Exits with code 1 if mismatches are found, useful as a lint step or pre-commit hook:

npx git-detect-case-change --check

Limit to specific paths

npx git-detect-case-change -- <dir-or-file>

Only check files changed since a ref

npx git-detect-case-change --since HEAD~3
npx git-detect-case-change --fix-local --since ORIG_HEAD

Post-merge hook

Automatically fix case mismatches after every git pull or git merge:

.git/hooks/post-merge:

#!/bin/sh
# post-merge — fix case mismatches introduced by the merge
set -e

# ORIG_HEAD points to where HEAD was before the merge
git rev-parse --verify ORIG_HEAD >/dev/null 2>&1 || exit 0

# Only check files that changed in the merge (fast even in large repos)
./node_modules/.bin/git-detect-case-change --fix-local --since ORIG_HEAD

Make the hook executable: chmod +x .git/hooks/post-merge

macOS and Windows default to case-insensitive filesystems. Git respects the underlying filesystem, so it can't reliably detect case-only renames.

The official workaround is:

git mv <old-path> <new-path>

This gets tedious when:

  • Many files changed at once
  • Renames came from automated refactors
  • You inherited case drift from someone else

This tool automates that detection. See this StackOverflow discussion for more context.

  1. Reads file paths from Git's index:

    git ls-tree --name-only -z -r HEAD

    -z uses NUL terminators so filenames with spaces or special characters are safe.

  2. Detects case mismatches:

    For each Git path, uses fs.promises.exists to look up the actual filesystem path in a case-insensitive way. Files are processed in batches of 100 to avoid file descriptor limits on large repos.

  3. Applies fixes based on mode:

    • Default mode: Stages changes with git mv <git-path> <local-path>

    • --fix-local mode: Renames local files/directories to match Git's case:

      • Directories first: Extracts unique directory changes and renames them (deepest first)
      • Files second: Renames remaining files with case-only differences
      • Two-step rename: Uses temporary path (file.tmp-<pid>-<timestamp>) to work around case-insensitive filesystem limitations
      • Transactional rollback: If the second rename fails, attempts to restore from temporary path to prevent data loss