# Windows and WSL2 line endings ThothII's containers execute shell scripts from the source checkout. Those files must stay LF, even when the PC normally uses CRLF. The repository's `.gitattributes` is authoritative, but a Windows Git setting or an old checkout can still leave incorrect bytes. Check line endings after every clone and pull, before building an image. ## Recommended WSL2 clone Use Docker Desktop with WSL2 integration. Clone inside the Linux filesystem, for example under `/home//src`, rather than under `/mnt/c`. This avoids slow cross-filesystem builds, permission surprises, and Windows tools rewriting files behind WSL. ```sh mkdir -p "$HOME/src" cd "$HOME/src" git -c core.autocrlf=false clone https://github.example.invalid/your-org/ThothII.git cd ThothII git config --local core.autocrlf false bash scripts/verify-line-endings.sh ``` Keep Docker Desktop's integration enabled for that WSL distribution. Run the Linux build scripts and the Linux `thothctl` binary from the same WSL shell. ## Repository-local LF policy Set the option in this repository only. Do not change a company-wide or personal Git policy just for ThothII. ```sh git config --local core.autocrlf false git config --local --get core.autocrlf ``` The second command must print `false`. `.gitattributes` keeps shell, YAML, Dockerfile, JSON, TypeScript, Python, and Markdown files at LF; PowerShell files remain CRLF. For a native PowerShell clone, disable conversion during the first checkout and then store the repository-local setting: ```powershell git -c core.autocrlf=false clone https://github.example.invalid/your-org/ThothII.git Set-Location ThothII git config --local core.autocrlf false & "C:\Program Files\Git\bin\bash.exe" scripts/verify-line-endings.sh ``` ## Verify after clone or pull From WSL2, Git Bash, macOS, or Linux run: ```sh bash scripts/verify-line-endings.sh ``` Success exits with code 0 and prints no offending path. If it lists a file, do not build or start ThothII. Correct the checkout first. Native PowerShell users can invoke the same script through Git for Windows as shown above. ## Recover an existing CRLF clone The safest recovery is to reclone into a new directory. First commit wanted work or copy it to a backup outside both clones. Then clone with conversion disabled, run the verifier, and copy back only reviewed changes. If a reviewed working tree must be repaired in place, Git must first normalize the index, export that exact index to a separate repair directory, verify the exported bytes, and only then copy the verified tracked files over the worktree. `git add --renormalize .` alone does not change existing worktree bytes. > **WARNING — destructive worktree rewrite.** Make a backup outside the clone or commit every > wanted tracked change before continuing. The copy step below overwrites tracked worktree bytes > from the staged index export. Stop if the staged diff does not contain exactly the wanted content; > untracked files are neither exported nor repaired. From WSL2, Git Bash, macOS, or Linux: ```sh git status --short git config --local core.autocrlf false git add --renormalize . git diff --cached --check git diff --cached REPAIR_DIR="$(cd .. && pwd -P)/ThothII-lf-repair" if [[ -e "$REPAIR_DIR" ]]; then echo "Choose a new empty LF repair directory: $REPAIR_DIR" >&2 exit 1 fi mkdir -p "$REPAIR_DIR" REPAIR_PREFIX="$REPAIR_DIR/" git checkout-index --all --force --prefix="$REPAIR_PREFIX" bash scripts/verify-line-endings.sh "$REPAIR_DIR" # WARNING: destructive copy; make a backup or commit wanted changes before this command. git ls-files -z | while IFS= read -r -d '' path; do cp "$REPAIR_DIR/$path" "$path" done bash scripts/verify-line-endings.sh ``` Native Windows PowerShell runs the same Git operations and invokes the byte verifier through Git for Windows: ```powershell git status --short git config --local core.autocrlf false git add --renormalize . git diff --cached --check git diff --cached $RepairDir = Join-Path (Split-Path -Parent (Get-Location).Path) 'ThothII-lf-repair' if (Test-Path $RepairDir) { throw 'Choose a new empty LF repair directory.' } New-Item -ItemType Directory -Path $RepairDir | Out-Null $RepairPrefix = $RepairDir.Replace('\', '/') + '/' git checkout-index --all --force --prefix=$RepairPrefix & "C:\Program Files\Git\bin\bash.exe" scripts/verify-line-endings.sh $RepairDir if ($LASTEXITCODE -ne 0) { throw 'The staged index export does not satisfy the LF policy.' } # WARNING: destructive copy; make a backup or commit wanted changes before this command. git ls-files | ForEach-Object { Copy-Item -LiteralPath (Join-Path $RepairDir $_) -Destination $_ -Force } & "C:\Program Files\Git\bin\bash.exe" scripts/verify-line-endings.sh if ($LASTEXITCODE -ne 0) { throw 'Tracked worktree bytes were not repaired to the LF policy.' } ``` The first verifier proves the exported index bytes before any overwrite; the final verifier examines the repaired worktree bytes and must also exit `0`. Review the staged diff again before committing, then remove the separate repair directory only after inspecting it. The procedure intentionally avoids `git reset --hard`; replacing the clone is easier to audit and much safer for uncommitted work.