Skip to content

fix(git): lowercase the git-username branch prefix - #24342

Open
innocarpe wants to merge 5 commits into
stablyai:mainfrom
innocarpe:fix-15857-branch-prefix-case
Open

innocarpe wants to merge 5 commits into
stablyai:mainfrom
innocarpe:fix-15857-branch-prefix-case

Conversation

@innocarpe

Copy link
Copy Markdown
Contributor

Description

git-username branch prefixes kept the GitHub login's signup case. GitHub treats that login as case-insensitive, but a case-insensitive filesystem stores EurFelux/ and eurfelux/ as the same ref directory. HEAD then names a branch git push cannot resolve.

Focused fix

  • In: selectBranchPrefixInput lowercases only the git-username strategy.
  • Out: custom prefixes, the none strategy, and the code that resolves which login to store.

Preserves

A custom prefix stays in the case the user typed. An already-lowercase login is unchanged. An empty or missing username still produces no prefix.

Evidence

node node_modules/vitest/vitest.mjs run --config config/vitest.config.ts --cache false src/shared/branch-prefix.test.ts — 32 passed.

The collision was not re-run on an APFS checkout.

User-regression-tradeoffs

New worktrees on a case-sensitive filesystem also use the lowercase prefix, so they no longer continue a mixed-case git-username namespace. Set Branch Prefix to Custom to keep a mixed-case namespace.

Fixes #15857

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: a7cf2874-06d3-4983-946b-4576999f6a10

📥 Commits

Reviewing files that changed from the base of the PR and between 3acae2440c5667ae6c7bd108544d9f1d55526183 and c71cd06.

📒 Files selected for processing (12)
  • src/main/ipc/worktree-logic.test.ts
  • src/renderer/src/components/settings/BranchPrefixFeedback.tsx
  • src/renderer/src/components/settings/GitPane.test.tsx
  • src/renderer/src/components/settings/GitPane.tsx
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/fr.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/shared/branch-prefix.test.ts
  • src/shared/branch-prefix.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 9d461bc4-ee79-4f30-9e5b-2678f092ffdf

📥 Commits

Reviewing files that changed from the base of the PR and between bf0e4638088abbf9cae541b66d32d3348cefa287 and 3acae2440c5667ae6c7bd108544d9f1d55526183.

📒 Files selected for processing (4)
  • src/renderer/src/components/settings/GitPane.test.tsx
  • src/renderer/src/components/settings/GitPane.tsx
  • src/shared/branch-prefix.test.ts
  • src/shared/branch-prefix.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.


📝 Walkthrough

Walkthrough

The Git-username branch-prefix strategy now prefers a valid lowercase username. If that form is invalid and the original username is valid, the strategy retains the original casing. The settings preview uses the selected value. Custom prefixes retain their entered casing. Tests cover lowercase output, the invalid-lowercase fallback, and custom-prefix casing.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 3acae

Git-username prefixes and settings previews now use consistent casing while preserving custom prefixes and valid original-case fallbacks. No actionable merge-blocking risk remains in the supplied evidence.

Security Architecture Review

Security architecture risk: ⚪ Minimal · up to 3acae

The change adjusts branch naming without changing account identity, permissions, or branch-creation authority. Existing validation remains in place, and custom-prefix casing is preserved. No material security risk was identified in the changed behavior.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated exposure change is limited to the branch-prefix value used by preview and branch construction. Lowercasing that value does not confer account privileges or move identity resolution into the renderer.

Trust Boundaries and Controls

  • observed — The selector is not the final enforcement boundary: it can return a lowercase value even when both casing forms are invalid. Main-process branch construction retains normalization, validation, the Git-username invalid-prefix fallback, and custom-prefix assertion. The preview change does not bypass those controls.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the problem, scope, behavior changes, trade-offs, linked issue, and targeted test result. However, it does not follow the repository template and omits required sections such … Reformat the description using the repository template. Add the missing required sections, include Visual Proof or state N/A with a reason, complete the Testing and Checklist items, and document cross-platform, SSH, security, performance, a…
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: lowercasing the Git username branch prefix.
Linked Issues check ✅ Passed Issue [#15857] requires a consistent branch prefix for the GitHub-login strategy. selectBranchPrefixInput now lowercases valid Git usernames and retains the original mixed-case value when the lowerc…
Out of Scope Changes check ✅ Passed The changes are limited to branch-prefix selection, the settings preview, and related tests. Custom prefixes and other strategies remain unchanged. These changes directly support issue [#15857]. No un…
Full details: Description check

Explanation

The description explains the problem, scope, behavior changes, trade-offs, linked issue, and targeted test result. However, it does not follow the repository template and omits required sections such as ELI5, What Changed, Why, Visual Proof or N/A, AI Disclosure, Review, Agent skill upstream boundary, Notes, and the Checklist.

Resolution

Reformat the description using the repository template. Add the missing required sections, include Visual Proof or state N/A with a reason, complete the Testing and Checklist items, and document cross-platform, SSH, security, performance, and compatibility considerations.

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Changes how git usernames are normalized for branch prefixes.

The PR appears safe to merge; no new actionable issue was found.

Summary

The PR lowercases Git-username branch prefixes, omits prefixes whose lowercase form Git rejects, and updates the settings preview and tests. Since the previous review, the only change moves a documentation comment; it introduces no new behavior.

Reviews (5) · Last reviewed commit: "docs(git): put the prefix selector note ..."

Comment thread src/shared/branch-prefix.ts Outdated

@pullfrog pullfrog Bot 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.

ℹ️ No critical issues — one minor suggestion inline.

Reviewed changes

  • Lowercase the git-username prefix — selectBranchPrefixInput now returns gitUsername.toLowerCase() for the git-username strategy, preserving null. This is the funnel for local, WSL, SSH, and runtime worktree-create, so new branches land in the lowercase ref namespace and no longer disagree with HEAD on case-insensitive filesystems. Custom and none strategies keep their behavior.
  • Tests — a mixed-case login lowercases, and a custom prefix keeps the user's typed case. The new assertion genuinely fails without the one-line change, so it is real coverage rather than theatre.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread src/shared/branch-prefix.ts Outdated
@innocarpe
innocarpe force-pushed the fix-15857-branch-prefix-case branch from bf0e463 to 3acae24 Compare October 1, 2026 11:09
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (3acae2440c)

The settings field and the branch preview now use the same prefix the worktree builder prepends. A mixed-case login still becomes lowercase when that form is a valid ref. A login such as Alice.LOCK stays in its original case, because alice.lock ends in .lock and git would reject it — previously that made worktree creation drop the prefix.

Comment thread src/shared/branch-prefix.ts Outdated

@pullfrog pullfrog Bot 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.

ℹ️ No critical issues — one minor suggestion inline.

Reviewed changes

  • Settings-pane preview now matches the branch that gets created — GitPane derives the previewed prefix from selectBranchPrefixInput instead of the raw repo gitUsername, so a mixed-case login previews as the lowercased prefix worktree-create will use. This addresses the prior pullfrog review.
  • Added a mixed-case fallback for git usernames whose lowercase form is an invalid ref — selectBranchPrefixInput returns the original login (e.g. Alice.LOCK) instead of a lowercase ref git rejects, with covering unit and settings-pane tests.
  • Refreshed the helper's JSDoc to document the lowercasing and the fallback.

The preview/JSDoc fix is correct and consistent across the main-process builder and the renderer. The remaining comment is about whether the new fallback is worth its cost on the case-insensitive filesystems this PR targets.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread src/shared/branch-prefix.ts Outdated
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (c9fe186016)

A git username whose lowercase form git rejects, such as Alice.LOCK, is no longer kept as the branch prefix. On a case-insensitive filesystem that prefix occupies the alice.lock lockfile path. The settings preview says no prefix will be applied. An already-lowercase invalid login still shows the existing rejection.

@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (c9fe186016)

A git username is still lowercased, but a login whose lowercase form git rejects is omitted instead of kept. Alice.LOCK would otherwise create refs/heads/Alice.LOCK/, which collides with the alice.lock lockfile on a case-insensitive filesystem. The settings preview says no prefix will be applied.

Comment thread src/renderer/src/components/settings/GitPane.tsx

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes

  • Dropped the mixed-case fallback in selectBranchPrefixInput: a login whose lowercase form git rejects (Alice.LOCK → alice.lock) now yields null instead of the original login, so no refs/heads/Alice.LOCK/ prefix is created and the settings preview shows No prefix will be applied. This addresses the prior pullfrog review's case-fold lockfile collision.
  • Refreshed the helper's JSDoc and added assertions that an already-lowercase invalid login (alice.lock, team x) is still returned so settings can surface the rejection.
  • Added GitPane and worktree-builder coverage: the preview no longer shows Alice.LOCK, and computeBranchName/computeValidatedBranchName both return the unprefixed name.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

innocarpe and others added 4 commits October 1, 2026 20:43
GitHub preserves signup case and treats the login as case-insensitive.
Using that case as a branch prefix collides with an existing lowercase
ref directory on APFS, so HEAD and the ref database disagree.
Custom prefixes stay as typed.
…lowercase form git rejects

Co-authored-by: Cursor <cursoragent@cursor.com>
Alice.LOCK lowercases to alice.lock. Keeping the original login creates
refs/heads/Alice.LOCK/, which collides with the alice.lock lockfile on a
case-insensitive filesystem. That prefix is now omitted, and the settings
preview no longer offers it.
A mixed-case login such as Alice.LOCK is left off new branches because
its lowercase form ends in .lock. Settings now says that, instead of
leaving the reason blank under the omitted prefix.
@innocarpe
innocarpe force-pushed the fix-15857-branch-prefix-case branch from c9fe186 to 01496ca Compare October 1, 2026 11:47
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (01496ca527)

Settings now explains that a username such as Alice.LOCK is omitted because lowercasing it ends in .lock, which Git rejects. An already-lowercase invalid login still shows the existing character warning.

@pullfrog pullfrog Bot 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.

ℹ️ No critical issues — one minor documentation-placement nit inline.

Reviewed changes

  • Explained an omitted username prefix — added gitUsernamePrefixOmission and the GitUsernamePrefixOmission = 'lowercase-lock' reason so BranchPrefixFeedback can say why the prefix is blank for a mixed-case login like Alice.LOCK, replacing the generic "No prefix will be applied"; copy added across all six locales.
  • Shared the omission decision — selectBranchPrefixInput now delegates the .lock case to that helper. The refactor is behavior-equivalent: an already-lowercase invalid login is still returned so the existing character warning explains it.
  • Coverage — branch-prefix.test.ts asserts the omission-reason matrix, and GitPane.test.tsx asserts the detailed settings message plus that it is not shown for a plain invalid username (team x).

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread src/shared/branch-prefix.ts
The selector description was sitting above the omission type, so the function itself had no note. The block now sits directly above selectBranchPrefixInput.
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (c71cd068e2)

The selector's description now sits on selectBranchPrefixInput again. The omission type keeps its own note.

This branch has not been deployed

No deployments
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.

[Bug]: worktree create uses the GitHub login verbatim as a branch prefix, colliding with the lowercase namespace on case-insensitive filesystems

1 participant