Skip to content

post-commit condensation fails on Windows bare repo worktrees (Access Denied on object rename) #455

@Joshua-Palamuttam

Description

@Joshua-Palamuttam

Bug Description

post-commit condensation fails on Windows when using a bare repo + worktree layout. Entire's go-git tries to rename() a temp file over an existing loose git object, but Windows refuses because git marks loose objects as read-only (-r--r--r--).

On Linux, rename() atomically replaces the destination regardless of permissions. On Windows, rename / MoveFile fails with "Access is denied" if the destination exists and is read-only.

Error

From .entire/logs/entire.log:

{
  "level": "WARN",
  "msg": "post-commit: condensation failed",
  "component": "checkpoint",
  "error": "failed to write checkpoint metadata: failed to ensure sessions branch: failed to store tree: rename C:\worktrees-SeekOut\command-center.git\objects\pack\tmp_obj_693070780 C:\worktrees-SeekOut\command-center.git\objects\4b\825dc642cb6eb9a060e54bf8d69288fbee4904: Access is denied."
}

Root Cause

  1. Git creates loose objects as read-only on Windows (-r--r--r--)
  2. Entire's go-git writes a temp file to objects/pack/tmp_obj_*
  3. go-git tries to rename() the temp file to the target path in objects/
  4. The target already exists and is read-only — Windows blocks the rename
  5. Checkpoint creation fails silently (the || true in the hook swallows it)

Repo Layout

command-center.git/          # bare repository
  objects/                   # shared object store (read-only files)
  hooks/                     # shared hooks
  main/                      # worktree
    .entire/

Workaround

We patched the post-commit hook to chmod u+w all loose objects before Entire runs:

#!/bin/sh
# Make loose objects writable before Entire's go-git tries to rename over them
git_dir=$(git rev-parse --git-common-dir 2>/dev/null)
if [ -n "$git_dir" ] && [ -d "$git_dir/objects" ]; then
    find "$git_dir/objects" -maxdepth 2 -type f \
      ! -path "*/pack/*.pack" ! -path "*/pack/*.idx" ! -path "*/pack/*.rev" \
      -exec chmod u+w {} + 2>/dev/null
fi

entire hooks git post-commit 2>/dev/null || true

Suggested Fix

In the Go code where go-git stores objects, before the rename call, either:

  1. Remove the destination file if it already exists (since it's the same content)
  2. Or chmod the destination to be writable before renaming

Environment

  • Entire CLI (installed via go install)
  • Windows 11 Pro 10.0.26100
  • Git for Windows (bash shell)
  • Bare repo + worktree layout via git clone --bare + git worktree add
  • core.filemode = false

Related

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