Skip to content

git worktree add "" (empty path) recursively deletes the current working directory, including .git #6346

Description

@shivakrishnakokkula

Setup

  • Git version: git version 2.55.0.windows.3 (64-bit, installer defaults)
  • OS: Windows 11 Home 10.0.26200
  • Shell: Git Bash (also reproduces from PowerShell)

Steps to reproduce

mkdir repro && cd repro
git init -q -b main
git config user.email t@t && git config user.name t
echo hi > a.txt && mkdir sub && echo x > sub/b.txt
git add -A && git commit -qm init

git worktree add "" -b tb HEAD

(The empty string typically arrives via an unset variable, e.g. git worktree add "$UNSET_VAR" -b tb origin/main — which is how this was hit in the wild.)

Expected behavior

The empty path is rejected up front with a fatal error and no side effects — no branch created, and certainly nothing deleted.

Actual behavior

Preparing worktree (new branch 'tb')
fatal: The empty string is not a valid path

Exit code 128 — and the entire contents of the current working directory have been recursively deleted, including .git:

$ ls -a
.  ..

The new branch is also created before the fatal (visible when the deletion is survived, e.g. because another process holds locks on part of the tree).

Only files/directories held open by running processes survive the sweep (Windows file locking), which is the only reason this is sometimes a partial rather than total loss.

Comparison with Linux git

Same commands on git version 2.53.0 (Ubuntu/WSL): git dies on an internal assertion — BUG: ... empty after sanitization? followed by SIGABRT (exit 134) — which is ugly, but the repository and working tree are left fully intact. The destructive deletion appears to be specific to the Windows build's handling of the empty path.

Notes / suspected mechanism

This looks like worktree add's failure-path junk cleanup (the code that removes a partially-created worktree directory on error) resolving the empty path to the current directory on Windows and running its recursive delete against it. The empty string should presumably be rejected by path validation before the junk-cleanup handlers are armed — on Linux the earlier BUG/assert fires first, on Windows execution gets far enough to arm and trigger the cleanup.

Real-world impact: this silently destroyed a full repository checkout (recovered only because the remote had everything) when a script passed an unset environment variable as the worktree path. Given the data-loss severity and the two-command repro, flagging this as high priority.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions