Files
ThothII/docs/install/windows-line-endings.md
T

5.1 KiB

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.

Use Docker Desktop with WSL2 integration. Clone inside the Linux filesystem, for example under /home/<user>/src, rather than under /mnt/c. This avoids slow cross-filesystem builds, permission surprises, and Windows tools rewriting files behind WSL.

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.

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:

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:

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:

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:

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.