Setup & configAlways fixable

Stop Git showing file permission changes as modifications

Git says files changed but only the mode differs — how do I ignore that?

Short answer

Git tracks the executable bit, so a file going from 100644 to 100755 counts as a change. Set core.fileMode false to ignore mode differences, or fix the bit properly with git update-index --chmod when it genuinely matters.

quick fix
git config core.fileMode false

Tell this repository to ignore executable-bit differences

Does this match your situation?

  • git diff shows 'old mode 100644 / new mode 100755' and nothing else.
  • Every file looks modified after copying the repo or using WSL.
  • A shell script isn't executable after cloning on Linux.
  • Working across Windows and a Unix container churns file modes.

Step-by-step fix

  1. Confirm the mode is the only difference

    A diff showing only mode lines means the content is byte-identical and Git is reporting a permissions change.

    step 1
    git diff
    # diff --git a/build.sh b/build.sh
    # old mode 100644
    # new mode 100755
    
  2. Ignore mode changes in this repository

    The right setting when the churn comes from your environment — a Windows filesystem, a mounted volume, or WSL — rather than from a real intent to change permissions.

    step 2
    git config core.fileMode false
    git status      # the phantom changes are gone
    

    Keep it local to the repository. Setting it globally hides genuine permission changes in projects where they matter.

  3. Discard mode changes already staged

    Turning the setting off stops new noise but doesn't clear what's already recorded. Reset those entries.

    step 3
    git config core.fileMode false
    git reset --hard HEAD
    git status
    
  4. Set the executable bit deliberately

    When a script genuinely needs to be executable, record it in the index directly — this works even from Windows, where the filesystem has no such bit.

    step 4
    git update-index --chmod=+x scripts/build.sh
    git commit -m "Make build script executable"
    
    # on Linux/macOS the normal way also works:
    chmod +x scripts/build.sh
    git add scripts/build.sh
    
  5. Check what mode Git has recorded

    The index is authoritative. 100755 is executable, 100644 is not.

    step 5
    git ls-files -s scripts/build.sh
    

Why this works

Git records a simplified mode for each file — 100644 for regular, 100755 for executable — because the executable bit genuinely matters for scripts and hooks. Windows has no such bit, and mounted or copied filesystems often report it inconsistently, so Git sees a change that reflects nothing you did. core.fileMode false tells Git to keep the mode already in the index and stop comparing, which is why it eliminates the noise without altering what's committed.

How to stop it happening again

  • Set core.fileMode false in repositories you use across Windows and WSL or containers.
  • Use git update-index --chmod=+x to set the bit deliberately, so it's committed once and correct everywhere.
  • Avoid copying repositories between filesystems that handle permissions differently.

Commands used in this guide

git config

Read and write Git settings for one repo, your user, or the whole machine.

git update-index

Manipulate the index directly - including telling Git to ignore changes to a tracked file.

git ls-files

List files in the index, with precise filters for state.

git diff

Show exactly what changed - between your files, the index, commits or branches.

Still stuck?

Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.

Browse all guides →

Frequently asked questions

What does 'old mode 100644 new mode 100755' mean?

The file's executable bit changed. 100644 is a regular file and 100755 is executable. Git tracks this because it matters for scripts, so it reports the change even though the content is identical.

How do I make Git ignore file permission changes?

git config core.fileMode false in that repository. Git then keeps whatever mode is already in the index and stops comparing against the filesystem, which removes the phantom modifications.

How do I make a script executable from Windows?

git update-index --chmod=+x path/to/script.sh, then commit. This writes the executable bit into the index directly, so it's correct for everyone who clones even though Windows has no such filesystem bit.

Related rescue guides

← All Git Rescue guides