mcpField
W
windows-git-bash-compatibility

windows-git-bash-compatibility

github.com/josiahsiegel云与 DevOps59161 次安装19 周前更新
代码仓库

关于 windows-git-bash-compatibility

面向在 Windows 上使用 Git Bash 的 Azure Data Factory 开发者,说明路径转换导致的问题,并介绍命令和 CI/CD 脚本的调整方法。

主要功能

  1. 01说明 Git Bash 路径转换
  2. 02介绍 MSYS_NO_PATHCONV 用法
  3. 03涵盖 npm、PowerShell 和 Azure CLI
  4. 04提供 Shell 检测模式
  5. 05介绍 CI/CD 脚本实践

适用场景

  1. 01修复 ADF npm 验证或导出命令
  2. 02从 Git Bash 运行 PowerShell 部署脚本
  3. 03使用 Azure CLI 部署 ARM 模板
  4. 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_NAMEWSL 发行版名称Ubuntu、Debian 等

资源

总结

要点:

  1. Git Bash 会自动将 Unix 风格的路径转换为 Windows 路径
  2. 使用 export MSYS_NO_PATHCONV=1 禁用转换
  3. 使用 $MSYSTEM 变量检测 Shell 环境
  4. 在团队使用的所有 Shell 中测试 CI/CD 脚本
  5. 使用 PowerShell Core(pwsh)编写跨平台脚本
  6. 在本地开发脚本中添加 Shell 检测

评论

支持 Markdown