关于 windows-git-bash-compatibility
面向在 Windows 上使用 Git Bash 的 Azure Data Factory 开发者,说明路径转换导致的问题,并介绍命令和 CI/CD 脚本的调整方法。
主要功能
- 01说明 Git Bash 路径转换
- 02介绍 MSYS_NO_PATHCONV 用法
- 03涵盖 npm、PowerShell 和 Azure CLI
- 04提供 Shell 检测模式
- 05介绍 CI/CD 脚本实践
适用场景
- 01修复 ADF npm 验证或导出命令
- 02从 Git Bash 运行 PowerShell 部署脚本
- 03使用 Azure CLI 部署 ARM 模板
- 04让脚本检测当前 Shell
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill windows-git-bash-compatibility安装后在 Claude Code 中输入/windows-git-bash-compatibility确认已加载。
详细介绍
Azure Data Factory 的 Windows 与 Git Bash 兼容性
概述
Azure Data Factory 开发通常在 Windows 计算机上进行,并使用 Git Bash(MINGW64)作为主要 shell。这会带来路径转换问题,可能导致 CI/CD 管道、npm 命令和部署脚本无法正常运行。
Git Bash 路径转换行为
自动路径转换
Git Bash(MINGW)会自动将 Unix 风格的路径转换为 Windows 路径:
转换示例:
/foo→C:/Program Files/Git/usr/foo/foo:/bar→C:\msys64\foo;C:\msys64\bar(路径列表)--dir=/foo→--dir=C:/msys64/foo(参数)
触发转换的情况:
- 参数中包含开头的正斜杠(
/) - 以冒号分隔的路径列表
-或,后带有路径组件的参数
不会触发转换的情况:
- 包含
=的参数(变量赋值) - 驱动器标识符(
C:) - 包含
;的参数(已经是 Windows 格式) - 以
//开头的参数(Windows 开关)
ADF 特有的路径问题
npm 构建命令
问题:
# This fails in Git Bash due to path conversion
npm run build validate ./adf-resources /subscriptions/abc/resourceGroups/rg/providers/Microsoft.DataFactory/factories/myFactory
# Path gets converted incorrectly
解决方案:
# Disable path conversion before running
export MSYS_NO_PATHCONV=1
npm run build validate ./adf-resources /subscriptions/abc/resourceGroups/rg/providers/Microsoft.DataFactory/factories/myFactory
# Or wrap the command
MSYS_NO_PATHCONV=1 npm run build export ./adf-resources /subscriptions/.../myFactory "ARMTemplate"
PowerShell 脚本
问题:
# Calling PowerShell scripts from Git Bash
pwsh ./PrePostDeploymentScript.Ver2.ps1 -armTemplate "./ARMTemplate/ARMTemplateForFactory.json"
# Path conversion may interfere
解决方案:
# Disable conversion for PowerShell calls
MSYS_NO_PATHCONV=1 pwsh ./PrePostDeploymentScript.Ver2.ps1 -armTemplate "./ARMTemplate/ARMTemplateForFactory.json"
ARM 模板路径
问题:
# Azure CLI deployment from Git Bash
az deployment group create \
--resource-group myRG \
--template-file ARMTemplate/ARMTemplateForFactory.json # Path may get converted
解决方案:
# Use relative paths with ./ prefix or absolute Windows paths
export MSYS_NO_PATHCONV=1
az deployment group create \
--resource-group myRG \
--template-file ./ARMTemplate/ARMTemplateForFactory.json
Shell 检测模式
Bash Shell 检测
#!/usr/bin/env bash
# Method 1: Check $MSYSTEM (Git Bash/MSYS2 specific)
if [ -n "$MSYSTEM" ]; then
echo "Running in Git Bash/MinGW ($MSYSTEM)"
export MSYS_NO_PATHCONV=1
fi
# Method 2: Check uname -s (more portable)
case "$(uname -s)" in
MINGW64*|MINGW32*|MSYS*)
echo "Git Bash detected"
export MSYS_NO_PATHCONV=1
;;
Linux*)
if grep -q Microsoft /proc/version 2>/dev/null; then
echo "WSL detected"
else
echo "Native Linux"
fi
;;
Darwin*)
echo "macOS"
;;
esac
# Method 3: Check $OSTYPE (bash-specific)
case "$OSTYPE" in
msys*)
echo "Git Bash/MSYS"
export MSYS_NO_PATHCONV=1
;;
linux-gnu*)
echo "Linux"
;;
darwin*)
echo "macOS"
;;
esac
Node.js Shell 检测
// detect-shell.js - For use in npm scripts or Node tools
function detectShell() {
const env = process.env;
// Git Bash/MinGW (MOST RELIABLE)
if (env.MSYSTEM) {
return {
type: 'mingw',
subsystem: env.MSYSTEM, // MINGW64, MINGW32, or MSYS
needsPathFix: true
};
}
// WSL
if (env.WSL_DISTRO_NAME) {
return {
type: 'wsl',
distro: env.WSL_DISTRO_NAME,
needsPathFix: false
};
}
// PowerShell (3+ paths in PSModulePath)
if (env.PSModulePath?.split(';').length >= 3) {
return {
type: 'powershell',
needsPathFix: false
};
}
// CMD
if (process.platform === 'win32' && env.PROMPT === '$P$G') {
return {
type: 'cmd',
needsPathFix: false
};
}
// Cygwin
if (env.TERM === 'cygwin') {
return {
type: 'cygwin',
needsPathFix: true
};
}
// Unix shells
if (env.SHELL?.includes('bash')) {
return { type: 'bash', needsPathFix: false };
}
if (env.SHELL?.includes('zsh')) {
return { type: 'zsh', needsPathFix: false };
}
return {
type: 'unknown',
platform: process.platform,
needsPathFix: false
};
}
// Usage
const shell = detectShell();
console.log(`Detected shell: ${shell.type}`);
if (shell.needsPathFix) {
process.env.MSYS_NO_PATHCONV = '1';
console.log('Path conversion disabled for Git Bash compatibility');
}
module.exports = { detectShell };
PowerShell 检测
# Detect PowerShell edition and version
function Get-ShellInfo {
$info = @{
Edition = $PSVersionTable.PSEdition
Version = $PSVersionTable.PSVersion
OS = $PSVersionTable.OS
Platform = $PSVersionTable.Platform
}
if ($info.Edition -eq 'Core') {
Write-Host "PowerShell Core (pwsh) - Cross-platform compatible" -ForegroundColor Green
$info.CrossPlatform = $true
} else {
Write-Host "Windows PowerShell - Windows only" -ForegroundColor Yellow
$info.CrossPlatform = $false
}
return $info
}
$shellInfo = Get-ShellInfo
CI/CD 管道模式
本地开发脚本
validate-adf.sh(兼容 Git Bash):
#!/usr/bin/env bash
set -e
# Detect and handle Git Bash
if [ -n "$MSYSTEM" ]; then
export MSYS_NO_PATHCONV=1
echo "🔧 Git Bash detected - path conversion disabled"
fi
# Configuration
ADF_ROOT="./adf-resources"
FACTORY_ID="/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.DataFactory/factories/${FACTORY_NAME}"
# Validate ADF resources
echo "📋 Validating ADF resources..."
npm run build validate "$ADF_ROOT" "$FACTORY_ID"
# Generate ARM templates
echo "📦 Generating ARM templates..."
npm run build export "$ADF_ROOT" "$FACTORY_ID" "ARMTemplate"
echo "✅ Validation complete"
deploy-adf.sh(跨平台):
#!/usr/bin/env bash
set -e
# Detect shell
detect_shell() {
if [ -n "$MSYSTEM" ]; then echo "git-bash"
elif [ -n "$WSL_DISTRO_NAME" ]; then echo "wsl"
elif [[ "$OSTYPE" == "darwin"* ]]; then echo "macos"
else echo "linux"
fi
}
SHELL_TYPE=$(detect_shell)
echo "🖥️ Detected shell: $SHELL_TYPE"
# Handle Git Bash
if [ "$SHELL_TYPE" = "git-bash" ]; then
export MSYS_NO_PATHCONV=1
fi
# Download PrePostDeploymentScript
curl -sLo PrePostDeploymentScript.Ver2.ps1 \
https://raw.githubusercontent.com/Azure/Azure-DataFactory/main/SamplesV2/ContinuousIntegrationAndDelivery/PrePostDeploymentScript.Ver2.ps1
# Stop triggers
echo "⏸️ Stopping triggers..."
MSYS_NO_PATHCONV=1 pwsh ./PrePostDeploymentScript.Ver2.ps1 \
-armTemplate "./ARMTemplate/ARMTemplateForFactory.json" \
-ResourceGroupName "$RESOURCE_GROUP" \
-DataFactoryName "$FACTORY_NAME" \
-predeployment $true \
-deleteDeployment $false
# Deploy ARM template
echo "🚀 Deploying ARM template..."
az deployment group create \
--resource-group "$RESOURCE_GROUP" \
--template-file ./ARMTemplate/ARMTemplateForFactory.json \
--parameters ./ARMTemplate/ARMTemplateParametersForFactory.json \
--parameters factoryName="$FACTORY_NAME"
# Start triggers
echo "▶️ Starting triggers..."
MSYS_NO_PATHCONV=1 pwsh ./PrePostDeploymentScript.Ver2.ps1 \
-armTemplate "./ARMTemplate/ARMTemplateForFactory.json" \
-ResourceGroupName "$RESOURCE_GROUP" \
-DataFactoryName "$FACTORY_NAME" \
-predeployment $false \
-deleteDeployment $true
echo "✅ Deployment complete"
包含 Shell 检测的 package.json
{
"scripts": {
"prevalidate": "node scripts/detect-shell.js",
"validate": "node node_modules/@microsoft/azure-data-factory-utilities/lib/index validate",
"prebuild": "node scripts/detect-shell.js",
"build": "node node_modules/@microsoft/azure-data-factory-utilities/lib/index export"
},
"dependencies": {
"@microsoft/azure-data-factory-utilities": "^1.0.3"
}
}
scripts/detect-shell.js:
const detectShell = () => {
if (process.env.MSYSTEM) {
console.log('🔧 Git Bash detected - disabling path conversion');
process.env.MSYS_NO_PATHCONV = '1';
return 'git-bash';
}
console.log(`🖥️ Shell: ${process.platform}`);
return process.platform;
};
detectShell();
常见问题与解决方案
问题 1:npm build validate 失败并显示“Resource not found”
症状:
npm run build validate ./adf-resources /subscriptions/abc/...
# Error: Resource '/subscriptions/C:/Program Files/Git/subscriptions/abc/...' not found
**原因:**Git Bash 转换了工厂 ID 路径
解决方案:
export MSYS_NO_PATHCONV=1
npm run build validate ./adf-resources /subscriptions/abc/...
问题 2:PowerShell 脚本路径不正确
症状:
pwsh PrePostDeploymentScript.Ver2.ps1 -armTemplate "./ARM/template.json"
# Error: Cannot find path 'C:/Program Files/Git/ARM/template.json'
**原因:**Git Bash 转换了 ARM 模板路径
解决方案:
MSYS_NO_PATHCONV=1 pwsh PrePostDeploymentScript.Ver2.ps1 -armTemplate "./ARM/template.json"
问题 3:Azure CLI 的 template-file 参数失败
症状:
az deployment group create --template-file ./ARMTemplate/file.json
# Error: Template file not found
**原因:**路径转换干扰了 Azure CLI
解决方案:
export MSYS_NO_PATHCONV=1
az deployment group create --template-file ./ARMTemplate/file.json
最佳实践
1. 在 .bashrc 中设置 MSYS_NO_PATHCONV
# Add to ~/.bashrc for Git Bash
if [ -n "$MSYSTEM" ]; then
export MSYS_NO_PATHCONV=1
fi
2. 创建包装脚本
# adf-cli.sh - Wrapper for ADF npm commands
#!/usr/bin/env bash
export MSYS_NO_PATHCONV=1
npm run build "$@"
3. 使用以 ./ 开头的相对路径
# Prefer this (less likely to trigger conversion)
./ARMTemplate/ARMTemplateForFactory.json
# Over this
ARMTemplate/ARMTemplateForFactory.json
4. 记录 Shell 要求
# README.md
## Development Environment
### Windows Users
- Use Git Bash or PowerShell Core (pwsh)
- Git Bash users: Add `export MSYS_NO_PATHCONV=1` to .bashrc
- Alternative: Use WSL2 for native Linux environment
5. 在多个 Shell 中测试
# Test matrix for Windows developers
- Git Bash (MINGW64)
- PowerShell Core 7+
- WSL2 (Ubuntu/Debian)
- cmd.exe (if applicable)
快速参考
| 环境变量 | 用途 | 值 |
|---|---|---|
MSYS_NO_PATHCONV | 禁用所有路径转换(Git for Windows) | 1 |
MSYS2_ARG_CONV_EXCL | 排除不进行转换的特定参数(MSYS2) | * 或模式 |
MSYSTEM | 当前 MSYS 子系统 | MINGW64、MINGW32、MSYS |
WSL_DISTRO_NAME | WSL 发行版名称 | Ubuntu、Debian 等 |
资源
总结
要点:
- Git Bash 会自动将 Unix 风格的路径转换为 Windows 路径
- 使用
export MSYS_NO_PATHCONV=1禁用转换 - 使用
$MSYSTEM变量检测 Shell 环境 - 在团队使用的所有 Shell 中测试 CI/CD 脚本
- 使用 PowerShell Core(pwsh)编写跨平台脚本
- 在本地开发脚本中添加 Shell 检测
评论
支持 Markdown