Skip to content

fix(config): keep git flake subdirectory refs as distinct inputs (#2704)#2877

Open
mikeland73 wants to merge 1 commit into
mainfrom
claude/focused-goldberg-7irqx0
Open

fix(config): keep git flake subdirectory refs as distinct inputs (#2704)#2877
mikeland73 wants to merge 1 commit into
mainfrom
claude/focused-goldberg-7irqx0

Conversation

@mikeland73

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2704.

Two git flake references that point at the same repository but different subdirectories (via the dir query parameter) are distinct inputs, but devbox deduplicated them and silently installed only one. For example:

"packages": [
  "git+ssh://git@gitlab.com/org/devbox-shims.git?dir=betteralign&ref=master&rev=17d2bedca4884176e0d08078aa42311053e531c2",
  "git+ssh://git@gitlab.com/org/devbox-shims.git?dir=recovergoroutine&ref=master&rev=593d44945851d912f0c2158c46cc76da445adc43"
]

Only dir=recovergoroutine ended up in devbox.lock and got installed.

Root cause

parseVersionedName (in internal/devconfig/configfile/packages.go) split every package string on @ to separate the name from the version. Git flake URLs legitimately contain an @ in their git@host authority, so both of the refs above parsed to the name git+ssh://git, with the rest of the URL (including the differentiating dir) dumped into the "version".

Config.Packages() then deduplicates packages by name (lo.UniqBy(p.Name) — used so that a version override wins over an included/plugin package). Because both refs shared the same parsed name, one of the two distinct inputs was dropped.

Fix

Treat flake references as unversioned in parseVersionedName, so the whole reference is used as the name. Flake refs aren't Devbox name@version packages, so this is also conceptually correct. This:

  • keeps refs that differ only by query parameters (such as dir) distinct, and
  • leaves versioned Devbox packages (python@3.10, emacsPackages.@@latest, …) and flake refs without an @ unchanged.

The flake-detection reuses the existing pkgtype.IsFlake helper (no import cycle — pkgtype does not depend on configfile). The package's VersionedName() output is unchanged for these refs, so no lockfile migration is needed.

Tests

  • TestParseVersionedName: added git-ssh-flake-with-dir and git-ssh-flake-without-query cases.
  • TestPackagesDoesNotDedupDistinctGitFlakes: new regression test asserting that Config.Packages() preserves both git flakes that differ only by dir.
ok  go.jetify.com/devbox/internal/devconfig/configfile
ok  go.jetify.com/devbox/internal/devconfig (TestPackagesDoesNotDedupDistinctGitFlakes PASS)

(The two pre-existing TestFindError permission sub-tests fail only when the suite runs as root and are unrelated to this change.)

cc @maxiem-ota-insight (issue author)

🤖 Generated with Claude Code

https://claude.ai/code/session_013x2JTaq6GPt4kX5bubQC2D


Generated by Claude Code

Two git flake references pointing at the same repository but different
subdirectories (via the `dir` query parameter) are distinct inputs, yet
devbox deduplicated them and only installed one.

The root cause was `parseVersionedName`: it split package strings on `@`
to separate name from version. Git flake URLs legitimately contain `@`
in their `git@host` authority, so e.g.

  git+ssh://git@gitlab.com/org/repo.git?dir=betteralign&ref=...&rev=...
  git+ssh://git@gitlab.com/org/repo.git?dir=recovergoroutine&ref=...&rev=...

both parsed to the name "git+ssh://git", with the rest dumped into the
"version". Config.Packages() then deduplicates by name (lo.UniqBy), so
one of the two inputs was silently dropped.

Fix: treat flake references as unversioned in parseVersionedName, so the
whole reference is used as the name. This keeps refs that differ only by
query parameters distinct while leaving versioned devbox packages (and
flake refs without an `@`) unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013x2JTaq6GPt4kX5bubQC2D
Copilot AI review requested due to automatic review settings June 21, 2026 14:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where Devbox incorrectly deduplicated distinct git flake inputs that point to the same repo but different subdirectories (via ?dir=...), caused by @ in git@host being misinterpreted as the name@version delimiter during package parsing.

Changes:

  • Update parseVersionedName to treat flake references as unversioned, preserving the full flake ref as the package name.
  • Extend TestParseVersionedName coverage for git+ssh://git@... flake URLs (with and without query params).
  • Add a regression test ensuring Config.Packages() does not deduplicate distinct git flake refs that differ only by dir.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
internal/devconfig/configfile/packages.go Detect flake references early and avoid splitting on @, preventing incorrect deduplication.
internal/devconfig/configfile/packages_test.go Adds test cases proving parseVersionedName preserves full git+ssh flake refs containing @.
internal/devconfig/config_test.go Adds regression test asserting Config.Packages() preserves distinct git flake inputs differing by dir.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Git repository subdirectories should be different inputs

3 participants