Skip to content

Init() reports AlreadyExisted = false when re-initializing a submodule, worktree or --separate-git-dir repository, hiding an ignored --initial-branch #138

Description

@matt-edmondson

What's wrong

GitInitBuilder.ProbeAsync (GitIntegration/Builders/GitInitBuilder.cs, around lines 128-147) decides whether a repository already exists at the target by running git rev-parse --git-dir. It returns true only when the answer is .git or .. The comment there assumes an absolute path always means "a repository exists, but as an ancestor, not here".

That assumption is false. git also prints an absolute path for a repository right at the target when its .git is a file pointing elsewhere, which covers:

  • a checked-out submodule (.git → ../.git/modules/x)
  • a linked worktree (.git → <main>/.git/worktrees/x)
  • a repository created with --separate-git-dir

Repro (git 2.43):

$ git init --separate-git-dir /tmp/sg s
$ git -C s rev-parse --git-dir
/tmp/sg
$ git init s
Reinitialized existing Git repository in /tmp/sg/

Failure scenario

Init(path) on any of those directories re-initializes the existing repository, yet GitInitResult.AlreadyExisted is false. The probe exists so callers learn that git re-initialized and silently ignored options such as --initial-branch (see CLAUDE.md). In these cases the caller is told a fresh repository was created with its requested initial branch, and neither is true.

Suggested fix

Compare paths rather than matching literal strings:

  • Non-bare: the repository is "here" when git -C <target> rev-parse --show-toplevel resolves to the same directory as the target, after normalizing both with Path.GetFullPath and resolving symlinks.
  • Bare: rev-parse --is-bare-repository is true and --absolute-git-dir equals the target.
  • Anything else, including an ancestor repository or a non-zero exit, is "not yet".

Acceptance criteria

Tests where AlreadyExisted is true for:

  • a --separate-git-dir repository
  • a linked worktree (git worktree add)

and still false for a plain subdirectory of an existing repository.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    readyFully specified; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions