You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

大小写不一致时如何获取Git仓库中创建时的原始文件名?

Windows/PowerShell与Git大小写冲突的解决方法

问题背景

Windows和PowerShell默认不区分文件名大小写,但Git严格区分大小写。当Git仓库中提交了a_TEST_file.txt这类大小写混合的文件后,若用户在PowerShell脚本中传入小写的a_test_file.txt,调用Git命令(如git log)会返回“文件未找到”,且Resolve-Path、Convert-Path这类PowerShell命令无法返回Git中存储的原始大小写文件名。

解决方法

不需要强制用户输入严格大小写的文件名,以下两种可靠方法可以获取正确的原始文件名:

方法1:通过Git命令直接获取仓库中的真实文件名

利用Git的git ls-files命令忽略大小写匹配仓库内的文件,直接返回Git存储的原始大小写文件名:

# 假设用户输入的文件路径为 $inputPath
$inputPath = ".\a_test_file.txt"
# 拆分路径为目录和文件名
$targetDir = Split-Path -Path $inputPath -Parent
$inputFileName = Split-Path -Path $inputPath -Leaf

# 在目标目录下执行git命令,忽略大小写匹配文件
$correctFileName = git -C $targetDir ls-files -i --exclude-standard -- $inputFileName
# 拼接得到正确的文件路径
$correctFullPath = Join-Path -Path $targetDir -ChildPath $correctFileName

说明:git ls-files -i参数会忽略大小写匹配仓库中已追踪的文件,返回的结果就是Git中存储的原始大小写文件名。

方法2:调用Windows API获取磁盘上的真实文件名

PowerShell内置Cmdlet返回的文件名会被自动转换大小写,直接调用Windows内核API可以获取磁盘上实际存储的文件名:

Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;

public class FileSystemHelper {
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool GetFullPathName(string lpFileName, uint nBufferLength, [Out] StringBuilder lpBuffer, IntPtr lpFilePart);
}
"@

function Get-RealFileName {
    param([string]$Path)
    $sb = New-Object System.Text.StringBuilder(260)
    [FileSystemHelper]::GetFullPathName($Path, $sb.Capacity, $sb, [IntPtr]::Zero)
    $fullPath = $sb.ToString()
    
    $dir = Split-Path -Path $fullPath -Parent
    $inputName = Split-Path -Path $fullPath -Leaf
    
    # 遍历目录匹配文件,返回真实大小写文件名
    foreach ($file in [System.IO.Directory]::GetFiles($dir, $inputName, [System.IO.SearchOption]::TopDirectoryOnly)) {
        return Split-Path -Path $file -Leaf
    }
    return $inputName
}

# 使用示例
$inputPath = ".\a_test_file.txt"
$realFileName = Get-RealFileName -Path $inputPath
$correctFullPath = Join-Path -Path (Split-Path $inputPath -Parent) -ChildPath $realFileName

说明:通过GetFullPathName获取完整路径后,遍历目录匹配文件,得到磁盘上实际存储的大小写文件名。

不推荐的方法:让Git忽略大小写

可以通过Git配置让其在Windows环境下忽略大小写,但这会导致跨平台同步时出现冲突,仅适合单一Windows环境使用:

git config core.ignorecase true

测试代码

New-Item -ItemType Directory -Path '.\a_test' | Out-Null
Push-Location -Path '.\a_test'
git init
'a test' | Set-Content -Path .\a_TEST_file.txt
git add .
git commit -m '提交测试文件'
git log .\a_TEST_file.txt
git log .\a_test_file.txt
$null -eq $(git log .\a_test_file.txt)

Get-ChildItem '.\a_TEST_file.txt'
Get-ChildItem '.\a_test_file.txt'
Get-ChildItem '.\a_test_file.txt' |
    Select-Object -Property Name,FullName,ResolvedTarget,PSPath
Resolve-Path -Path '.\a_test_file.txt'
Convert-Path -Path '.\a_test_file.txt'

Pop-Location
Remove-Item -Recurse -Force -Path '.\a_test'

命令执行结果

PS C:\src> New-Item -ItemType Directory -Path '.\a_test' | Out-Null
PS C:\src> Push-Location -Path '.\a_test'
PS C:\src\a_test> git init
已初始化空的 Git 仓库于 C:/src/a_test/.git/
PS C:\src\a_test> 'a test' | Set-Content -Path .\a_TEST_file.txt
PS C:\src\a_test> git add .
PS C:\src\a_test> git commit -m '提交测试文件'
[main (根提交) 7fd198b] 提交测试文件
 1 file changed, 1 insertion(+)
 create mode 100644 a_TEST_file.txt
PS C:\src\a_test> git log .\a_TEST_file.txt
commit 7fd198b556dd1dabf8c9a47369e71d424cf995bd (HEAD -> main)
Author: lit <lit@myco.com>
Date:   Sat Nov 18 04:40:29 2023 -0600

    提交测试文件
PS C:\src\a_test> git log .\a_test_file.txt
PS C:\src\a_test> $null -eq $(git log .\a_test_file.txt)
True
PS C:\src\a_test>
PS C:\src\a_test> Get-ChildItem '.\a_TEST_file.txt'

    目录: C:\src\a_test

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2023-11-18    04:40              8 a_TEST_file.txt

PS C:\src\a_test> Get-ChildItem '.\a_test_file.txt'

    目录: C:\src\a_test

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          2023-11-18    04:40              8 a_test_file.txt

PS C:\src\a_test> Get-ChildItem '.\a_test_file.txt' | Select-Object -Property Name,FullName,ResolvedTarget,PSPath

Name            FullName                      ResolvedTarget                PSPath
----            --------                      --------------                ------
a_test_file.txt C:\src\a_test\a_test_file.txt C:\src\a_test\a_test_file.txt Microsoft.PowerShell.Core\FileSystem::C:\src\a_test\a_test_file.txt

PS C:\src\a_test> Resolve-Path -Path '.\a_test_file.txt'

Path
----
C:\src\a_test\a_test_file.txt

PS C:\src\a_test> Convert-Path -Path '.\a_test_file.txt'
C:\src\a_test\a_test_file.txt
PS C:\src\a_test>
PS C:\src\a_test> Pop-Location
PS C:\src> Remove-Item -Recurse -Force -Path '.\a_test'
PS C:\src>

内容的提问来源于stack exchange,提问作者lit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:17:08