Skip to the content.

This powershell script renames Git file names to match the actual casing on disk.

<#
.SYNOPSIS
This script renames Git file names to match the actual casing on disk.
.NOTES
Manual git commit is required after running this script.
#>

[CmdletBinding(SupportsShouldProcess=$true)]
param
(
    [Parameter(Mandatory=$true, Position=0)]
    [string]$folderPath,

    [Parameter()]
    [switch]$ShowDetails
)

# Get all files from Git for the specified folder
$gitFiles = git ls-files $folderPath

if ($ShowDetails) 
{
    Write-Host "Git files:"
    foreach ($file in $gitFiles) 
    {
        Write-Host $file
    }
}

# Get actual files on disk for the specified folder
$diskFiles = Get-ChildItem -Path $folderPath -Recurse -File | ForEach-Object { $_.FullName.Replace($PWD.Path + '\', '').Replace('\', '/') }

if ($ShowDetails) 
{
    Write-Host "`nDisk files:"
    foreach ($file in $diskFiles) 
    {
        Write-Host $file
    }
}

# Compare and find case mismatches
foreach ($gitFile in $gitFiles) 
{
    if ($ShowDetails) 
    {
        Write-Host "Checking: $gitFile"
    }
    $diskFile = $diskFiles | Where-Object { $_ -ieq $gitFile }
    if ($diskFile -and ($diskFile -cne $gitFile)) 
    {
        Write-Host "Case mismatch found:"
        Write-Host "Git:  $gitFile"
        Write-Host "Disk: $diskFile"
        
        # Create temporary name
        $tempName = $gitFile + ".temp"
        
        $operation = "Rename Git file from '$gitFile' to '$diskFile'"
        if ($PSCmdlet.ShouldProcess($gitFile, $operation)) 
        {
            # Two-step rename to handle case sensitivity
            git mv $gitFile $tempName
            git mv $tempName $diskFile
        }
    }
}