Skip to content

init prints success after post-clone steps fail #22

Description

@leogdion

Labels: bug
Priority: should-fix
Source: claude

Summary

git trees init checks whether the bare clone succeeded but not whether any of
the three steps that make the container usable succeeded. A half-configured
container still prints initialized … and exits 0.

Evidence

The clone is handled correctly, with rollback (git-trees:188-191):

if ! git clone --bare "$url" "$dir/trees-bare.git"; then
  rm -rf "$dir"
  return 1
fi

The next three commands are unchecked (git-trees:195-197):

git -C "$dir" config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
git -C "$dir" fetch origin
git -C "$dir" remote set-head origin --auto >/dev/null 2>&1

With no set -e, execution continues past any failure to _seed_agents and
then to echo "initialized $dir (default branch: $def)".

The fetch refspec step is exactly what makes remote-tracking refs work in a
bare clone (a bare clone does not set it up — the README calls this out). If
fetch fails, the container has no origin/* refs, so the very next thing a
user does breaks: git trees add <branch> cannot resolve origin/<default>,
and _default_branch silently falls back to the literal string main
(git-trees:56), which may not exist.

A plausible trigger: the clone succeeds against a reachable host, then the
network drops, or credentials work for read-only clone but the fetch is
interrupted. The user sees "initialized" and a broken container.

Proposed fix

Chain the post-clone steps and roll back on failure, matching the clone path.
set-head --auto is genuinely optional (it fails harmlessly on a remote with
no HEAD), so leave it unchecked:

if ! git -C "$dir" config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*' \
  || ! git -C "$dir" fetch origin; then
  echo "git trees init: clone succeeded but fetch/config failed — removing $dir" >&2
  rm -rf "$dir"
  return 1
fi
git -C "$dir" remote set-head origin --auto >/dev/null 2>&1

Rollback is preferable to leaving the directory: a novice who retries init
otherwise hits git trees init: $dir already exists (git-trees:185) and has
to know to rm -rf first.

Test plan

  • Happy path over file:// still initializes and prints the default branch
  • Simulate a post-clone fetch failure → nonzero exit, no false
    "initialized", directory removed
  • After a failed init, re-running the same command works (no stale dir)
  • CI runs an offline file:// init (see the CI coverage issue — init is
    currently untested)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions