Skip to content

Release v1.20.0: diff-loading fixes - #65

Merged
kboom merged 1 commit into
release/v1from
main
Jul 20, 2026
Merged

kboom merged 1 commit into
release/v1from
main

Conversation

@kboom

@kboom kboom commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Promote the diff-loading fixes from main to release/v1 to cut a normal v1.20.0 release.

Merging this PR triggers ci-release.yml, which tags v1.20.0, builds the VSIX, and creates a draft GitHub Release with the VSIX attached. Publishing that draft release then pushes it to the VS Marketplace via publish.yml.

Included

…ing (#64)

## Summary

The git tree filter would silently fail to load the diff (the explorer
list wouldn't budge, and the settings button never appeared) under
several real-world conditions. This PR fixes four distinct root causes
found via systematic debugging, each backed by a regression test.

All work follows TDD: every fix has a test that is RED before the change
and GREEN after. Full `GitTreeFilter.Core` suite: **84/84 passing**.

## Bugs fixed

**Bug #1 — Detached HEAD (`735f689`)**
`AssertValidReference` rejected a detached HEAD and threw
`HeadNotFoundException`, deactivating the plugin. Now tolerates detached
HEAD via a `Head?.Tip == null` guard.

**Bug #2 — Worktrees / submodules not detected (`b0d68ef`)**
VS `IGitExt.ActiveRepositories` is empty for worktrees, so the plugin
reported "Could not identify GIT repository". Added
`GitRepositoryDiscovery` which falls back to LibGit2Sharp
`Repository.Discover`.

**Bug #3 — Modern git index checksum error (`3a6cd86`)**
On large repos with a modern index (`UNTR` extension) the diff failed
with *"invalid data in index — calculated checksum does not match
expected"*. Root cause: the old LibGit2Sharp `0.27.0-preview` (libgit2
~1.0) couldn't parse a modern index. Upgraded to **LibGit2Sharp 0.31.0**
(libgit2 1.8), which VS itself ships.

**Bug #4 — Repo owned by another user (`b35c7fd`)**
The 0.31 upgrade pulled in libgit2 1.8, which enforces the
CVE-2022-24765 "dubious ownership" check. On enterprise machines a
worktree/clone owned by a different account made `new Repository(path)`
throw *"repository path … is not owned by current user"* inside
`SetUpAsync`. That exception escaped the async service factory, leaving
`SGitFilterService` null → *"Cannot find an instance of the
GitTreeFilter.IGitFilterService service"* ("cannot open").
- **Root cause fix:** `GlobalSettings.SetOwnerValidation(false)` in
`GitRepositoryFactory.Create` — VS already opened the repo for the user
and the plugin only reads it.
- **Defense in depth:** wrapped the fallible body of `SetUpAsync` in
try/catch so any future setup exception degrades the plugin to
`INACTIVE` (with the reason logged to the output pane) instead of
nulling the whole service.

Also added thread-safe Output-pane diagnostics across the activation
flow (`a246704`) to make future issues diagnosable from the log.

## Testing
- New/updated regression tests: detached HEAD, worktree discovery,
`ModernIndexChangesetTest`, `RepositoryOwnershipTest` — each RED before
its fix, GREEN after.
- Full `GitTreeFilter.Core` suite: 84/84.
- End-to-end: rebuilt the Release VSIX and verified against a real
enterprise worktree — the filter now activates and loads the diff.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@kboom
kboom merged commit ea4839c into release/v1 Jul 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant