| name | windows-git-bash-paths |
| description | Windows and Git Bash path handling for SSDT, SqlPackage, and DACPAC files.
PROACTIVELY activate for: (1) SqlPackage failing on Git Bash with path errors, (2) DACPAC file path conversion (MSYS, MINGW), (3) shell detection (PowerShell vs Git Bash) for SSDT scripts, (4) MSYS_NO_PATHCONV usage, (5) Windows-style backslash paths in publish profiles, (6) running dotnet build of .sqlproj from Git Bash, (7) cross-platform pipeline compatibility, (8) line-ending issues in SQL files.
Provides: SqlPackage path-conversion recipes, shell-detection helpers, dotnet build patterns from bash, and CRLF/LF normalization steps.
|
🚨 CRITICAL GUIDELINES
Windows File Path Requirements
MANDATORY: Always Use Backslashes on Windows for File Paths
When using Edit or Write tools on Windows, you MUST use backslashes (\) in file paths, NOT forward slashes (/).
Examples:
- ❌ WRONG:
D:/repos/project/file.tsx
- ✅ CORRECT:
D:\repos\project\file.tsx
This applies to:
- Edit tool file_path parameter
- Write tool file_path parameter
- All file operations on Windows systems
Documentation Guidelines
NEVER create new documentation files unless explicitly requested by the user.
- Priority: Update existing README.md files rather than creating new documentation
- Repository cleanliness: Keep repository root clean - only README.md unless user requests otherwise
- Style: Documentation should be concise, direct, and professional - avoid AI-generated tone
- User preference: Only create additional .md files when user specifically asks for documentation
Windows and Git Bash Path Handling for SSDT
Overview
SQL Server development is Windows-heavy, and many developers use Git Bash (MINGW/MSYS2) as their preferred shell on Windows. This creates unique path conversion challenges when working with Windows-native tools like SqlPackage, MSBuild, and Visual Studio that expect Windows-style paths.
This skill provides comprehensive guidance on handling path conversion issues, shell detection, and best practices for SSDT workflows on Windows with Git Bash.
The Path Conversion Problem
What Happens in Git Bash/MINGW
Git Bash automatically converts POSIX-style paths to Windows paths, but this can cause issues with command-line arguments:
Automatic Conversions:
/foo → C:/Program Files/Git/usr/foo
/foo:/bar → C:\msys64\foo;C:\msys64\bar
--dir=/foo → --dir=C:/msys64/foo
Problematic for SqlPackage:
sqlpackage /Action:Publish /SourceFile:MyDB.dacpac
What Triggers Conversion
✓ Leading forward slash (/) in arguments
✓ Colon-separated path lists
✓ Arguments after - or , with path components
What's Exempt
✓ Arguments containing = (variable assignments)
✓ Drive specifiers (C:)
✓ Arguments with ; (already Windows format)
✓ Arguments starting with // (Windows switches)
Solutions for SqlPackage in Git Bash
Method 1: MSYS_NO_PATHCONV (Recommended)
Disable path conversion for specific commands:
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish \
/SourceFile:"MyDatabase.dacpac" \
/TargetServerName:"localhost" \
/TargetDatabaseName:"MyDB"
MSYS_NO_PATHCONV=1 sqlpackage /Action:Extract \
/SourceConnectionString:"Server=localhost;Database=MyDB;Integrated Security=True;" \
/TargetFile:"MyDB_backup.dacpac"
Important Notes:
- The VALUE doesn't matter - setting to
0, false, or empty still disables conversion
- Only matters that variable is DEFINED
- To re-enable:
env -u MSYS_NO_PATHCONV
Method 2: Double Slash // (Alternative)
Use double slashes for SqlPackage parameters:
sqlpackage //Action:Publish \
//SourceFile:MyDatabase.dacpac \
//TargetServerName:localhost \
//TargetDatabaseName:MyDB
sqlpackage //Action:Extract \
//SourceConnectionString:"Server=localhost;Database=MyDB;Integrated Security=True;" \
//TargetFile:output.dacpac
Advantages:
- No environment variable needed
- Works across shells
- Shell-agnostic scripts
Method 3: Use Windows-Style Paths with Quotes
Always quote paths with backslashes:
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish \
/SourceFile:"D:\Projects\MyDB\bin\Release\MyDB.dacpac" \
/TargetConnectionString:"Server=localhost;Database=MyDB;Integrated Security=True;"
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish \
/SourceFile:"D:/Projects/MyDB/bin/Release/MyDB.dacpac" \
/TargetConnectionString:"Server=localhost;Database=MyDB;Integrated Security=True;"
Method 4: Switch to PowerShell or CMD
For Windows-native tools, consider using native shells:
# PowerShell (recommended for Windows SSDT workflows)
sqlpackage /Action:Publish `
/SourceFile:"MyDatabase.dacpac" `
/TargetServerName:"localhost" `
/TargetDatabaseName:"MyDB"
:: CMD
sqlpackage /Action:Publish ^
/SourceFile:"MyDatabase.dacpac" ^
/TargetServerName:"localhost" ^
/TargetDatabaseName:"MyDB"
Shell Detection for Scripts
Bash Script Detection
#!/bin/bash
case "$OSTYPE" in
msys*)
export MSYS_NO_PATHCONV=1
SQLPACKAGE_ARGS="/Action:Publish /SourceFile:MyDB.dacpac"
;;
cygwin*)
export MSYS_NO_PATHCONV=1
SQLPACKAGE_ARGS="/Action:Publish /SourceFile:MyDB.dacpac"
;;
linux-gnu*)
SQLPACKAGE_ARGS="/Action:Publish /SourceFile:MyDB.dacpac"
;;
darwin*)
SQLPACKAGE_ARGS="/Action:Publish /SourceFile:MyDB.dacpac"
;;
esac
sqlpackage $SQLPACKAGE_ARGS
case "$(uname -s)" in
MINGW64*|MINGW32*)
export MSYS_NO_PATHCONV=1
echo "Git Bash detected - path conversion disabled"
;;
MSYS_NT*)
export MSYS_NO_PATHCONV=1
echo "MSYS detected - path conversion disabled"
;;
CYGWIN*)
export MSYS_NO_PATHCONV=1
echo "Cygwin detected - path conversion disabled"
;;
Linux*)
echo "Linux detected"
;;
Darwin*)
echo "macOS detected"
;;
esac
if [ -n "$MSYSTEM" ]; then
export MSYS_NO_PATHCONV=1
echo "MSYS environment detected: $MSYSTEM"
case "$MSYSTEM" in
MINGW64) echo "64-bit native Windows environment" ;;
MINGW32) echo "32-bit native Windows environment" ;;
MSYS) echo "POSIX-compliant environment" ;;
esac
fi
Complete Build Script Example
#!/bin/bash
set -e
if [ -n "$MSYSTEM" ]; then
echo "Git Bash/MSYS2 detected - disabling path conversion"
export MSYS_NO_PATHCONV=1
fi
PROJECT_NAME="MyDatabase"
BUILD_CONFIG="Release"
DACPAC_PATH="bin/${BUILD_CONFIG}/${PROJECT_NAME}.dacpac"
TARGET_SERVER="${SQL_SERVER:-localhost}"
TARGET_DB="${SQL_DATABASE:-MyDB}"
echo "Building ${PROJECT_NAME}..."
dotnet build "${PROJECT_NAME}.sqlproj" -c "$BUILD_CONFIG"
if [ ! -f "$DACPAC_PATH" ]; then
echo "ERROR: DACPAC not found at $DACPAC_PATH"
exit 1
fi
echo "DACPAC built successfully: $DACPAC_PATH"
echo "Deploying to ${TARGET_SERVER}/${TARGET_DB}..."
sqlpackage //Action:Publish \
//SourceFile:"$DACPAC_PATH" \
//TargetServerName:"$TARGET_SERVER" \
//TargetDatabaseName:"$TARGET_DB" \
//p:BlockOnPossibleDataLoss=False
echo "Deployment complete!"
Common SSDT Path Issues in Git Bash
Issue 1: DACPAC File Paths
Problem:
sqlpackage /Action:Publish /SourceFile:./bin/Release/MyDB.dacpac
Solution:
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish \
/SourceFile:"./bin/Release/MyDB.dacpac"
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish \
/SourceFile:"D:/Projects/MyDB/bin/Release/MyDB.dacpac"
sqlpackage //Action:Publish //SourceFile:./bin/Release/MyDB.dacpac
Issue 2: SQL Project File Paths
Problem:
dotnet build "D:/Program Files/MyProject/Database.sqlproj"
msbuild "D:/Program Files/MyProject/Database.sqlproj"
Solution:
dotnet build "D:/Program Files/MyProject/Database.sqlproj"
msbuild "D:\Program Files\MyProject\Database.sqlproj"
msbuild "D:/PROGRA~1/MyProject/Database.sqlproj"
Issue 3: Publish Profile Paths
Problem:
sqlpackage /Action:Publish \
/SourceFile:MyDB.dacpac \
/Profile:./Profiles/Production.publish.xml
Solution:
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish \
/SourceFile:"MyDB.dacpac" \
/Profile:"./Profiles/Production.publish.xml"
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish \
/SourceFile:"D:/Projects/MyDB.dacpac" \
/Profile:"D:/Projects/Profiles/Production.publish.xml"
Issue 4: Connection Strings
Problem:
/SourceConnectionString:"Server=localhost;Database=MyDB;Integrated Security=True;AttachDbFilename=D:/Data/MyDB.mdf"
Solution:
MSYS_NO_PATHCONV=1 sqlpackage /Action:Extract \
/SourceConnectionString:"Server=localhost;Database=MyDB;Integrated Security=True;AttachDbFilename=D:\Data\MyDB.mdf" \
/TargetFile:"output.dacpac"
/SourceConnectionString:"Server=localhost;Database=MyDB;Integrated Security=True;AttachDbFilename=D:\\Data\\MyDB.mdf"
CI/CD Considerations
GitHub Actions with Git Bash
name: SSDT Build and Deploy
on: [push]
jobs:
build:
runs-on: windows-latest
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Install SqlPackage
run: dotnet tool install -g Microsoft.SqlPackage
- name: Build Database Project
run: dotnet build Database.sqlproj -c Release
- name: Deploy with Path Conversion Disabled
env:
MSYS_NO_PATHCONV: 1
run: |
sqlpackage /Action:Publish \
/SourceFile:"bin/Release/MyDatabase.dacpac" \
/TargetServerName:"localhost" \
/TargetDatabaseName:"MyDB"
PowerShell Alternative (Recommended for Windows)
jobs:
build:
runs-on: windows-latest
defaults:
run:
shell: pwsh
steps:
- name: Deploy Database
run: |
sqlpackage /Action:Publish `
/SourceFile:"bin/Release/MyDatabase.dacpac" `
/TargetServerName:"localhost" `
/TargetDatabaseName:"MyDB"
Best Practices Summary
For Interactive Development
- Use PowerShell or CMD for SSDT on Windows - avoids path conversion issues entirely
- If using Git Bash, set
MSYS_NO_PATHCONV=1 in your shell profile for SSDT work
- Always quote paths containing spaces or special characters
- Use absolute paths when possible to avoid ambiguity
For Scripts
- Detect shell environment and set
MSYS_NO_PATHCONV=1 conditionally
- Use double-slash // syntax for SqlPackage arguments (most portable)
- Prefer PowerShell for Windows-specific workflows (build scripts, CI/CD)
- Test scripts on all target platforms (Windows PowerShell, Git Bash, Linux)
For CI/CD
- Use PowerShell shell in GitHub Actions for Windows runners (
shell: pwsh)
- Self-hosted Windows agents - use native Windows paths and shells
- Set MSYS_NO_PATHCONV=1 as environment variable if Git Bash required
- Prefer dotnet CLI over MSBuild for cross-platform compatibility
For Teams
- Document shell requirements in repository README
- Provide scripts for all shells (bash, PowerShell, CMD)
- Standardize on PowerShell for Windows SSDT workflows when possible
- Use containerized builds to avoid shell-specific issues
Quick Reference
Environment Variables
export MSYS_NO_PATHCONV=1
env -u MSYS_NO_PATHCONV
SqlPackage Command Templates
MSYS_NO_PATHCONV=1 sqlpackage /Action:Publish /SourceFile:"MyDB.dacpac" /TargetServerName:"localhost" /TargetDatabaseName:"MyDB"
sqlpackage //Action:Publish //SourceFile:MyDB.dacpac //TargetServerName:localhost //TargetDatabaseName:MyDB
sqlpackage /Action:Publish /SourceFile:"MyDB.dacpac" /TargetServerName:"localhost" /TargetDatabaseName:"MyDB"
sqlpackage /Action:Publish /SourceFile:"MyDB.dacpac" /TargetServerName:"localhost" /TargetDatabaseName:"MyDB"
Shell Detection One-Liners
[ -n "$MSYSTEM" ] && echo "Git Bash/MSYS2 detected"
[[ "$(uname -s)" =~ ^MINGW ]] && echo "Git Bash detected"
[ -n "$MSYSTEM" ] && export MSYS_NO_PATHCONV=1
Resources
Troubleshooting
"Invalid parameter" errors
Symptom: SqlPackage reports "Invalid parameter" or "Unknown action"
Cause: Git Bash converting /Action to a file path
Fix: Use MSYS_NO_PATHCONV=1 or double-slash //Action
"File not found" with valid paths
Symptom: DACPAC or project file not found despite correct path
Cause: Path conversion mangling the file path
Fix: Quote paths and use MSYS_NO_PATHCONV=1
Build succeeds but publish fails
Symptom: dotnet build works but sqlpackage fails
Cause: dotnet CLI handles paths correctly, but SqlPackage uses / parameters
Fix: Use MSYS_NO_PATHCONV=1 for SqlPackage commands only
Spaces in paths cause errors
Symptom: Paths with "Program Files" or other spaces fail
Cause: Unquoted paths split into multiple arguments
Fix: Always quote paths: /SourceFile:"D:/Program Files/MyDB.dacpac"