Skip to content

fix: normalize branch names in CLI and UI#6

Merged
MusicMaster4 merged 3 commits into
mainfrom
testing
Jul 10, 2026
Merged

fix: normalize branch names in CLI and UI#6
MusicMaster4 merged 3 commits into
mainfrom
testing

Conversation

@MusicMaster4

Copy link
Copy Markdown
Owner

Summary

  • Normalize branch names in CLI and UI to follow standard conventions
  • Update CLI help text for checkout command to reflect new ck alias
  • Introduce sanitizeBranchName utility to handle complex branch name transformations
  • Add tests for sanitizeBranchName to ensure correctness

Test plan

  • Run npm test to execute the test suite for sanitizeBranchName
  • Verify that all tests pass without errors
  • Manually test the ck alias in the CLI by switching to various branches, including those with special characters or non-standard naming
  • Confirm that the ck alias correctly resolves to the sanitized branch name

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces a shared sanitizeBranchName utility (lib/branch-name.ts) that normalises accent characters, replaces spaces/underscores with hyphens, collapses .. sequences, and strips leading/trailing separators, then wires it into the CLI (resolveBranchName wrapper) and the React UI. The HTML tool's normalizeBranch is updated to match.

  • New utility + tests: sanitizeBranchName centralises all branch-name transformation logic; a test suite covers accents, special chars, .. collapse, and empty input.
  • CLI integration: resolveBranchName wraps the utility with empty-string guards and a user-visible "corrected" log line, replacing ad-hoc die() calls in the branch, merge, and switch commands.
  • HTML parity: normalizeBranch in the standalone HTML tool is rewritten to mirror the lib, including the previously missing .. collapse.

Confidence Score: 4/5

Safe to merge once the leading/trailing dot strip is added to both sanitization functions.

Both sanitizeBranchName (lib) and normalizeBranch (HTML) strip leading/trailing hyphens and slashes but leave leading/trailing dots intact. Git's ref-format rules reject any name that starts or ends with a dot, so inputs such as .feature or feature. pass sanitization and then cause a hard git checkout / git branch failure. The fix is a one-liner in each place; everything else in the PR is solid.

lib/branch-name.ts and GIT Command Generator.html both need a trailing dot-strip step added to their sanitization chains.

Important Files Changed

Filename Overview
lib/branch-name.ts New utility: handles accent normalization, special char removal, and .. collapse correctly, but does not strip leading/trailing dots — git rejects such refs.
GIT Command Generator.html Updated normalizeBranch to mirror lib/branch-name.ts, including the .. collapse, but shares the same missing leading/trailing dot trim.
scripts/cli.ts Adds resolveBranchName wrapper for validation/logging; uses it for branch, merge, and switch commands. Correctness of results depends on the underlying sanitizeBranchName.
app/HomeClient.tsx Replaces inline normalizeBranch with the shared sanitizeBranchName import — straightforward refactor with no logic change.
test/branch-name.test.ts Good coverage of accent normalization, special chars, slash/dot collapsing, and empty input. Missing test cases for leading/trailing standalone dots (e.g., .feature, feature.).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Raw user input] --> B["normalize NFD"]
    B --> C["remove combining marks"]
    C --> D["spaces/underscores to hyphen"]
    D --> E["remove invalid chars"]
    E --> F["collapse hyphens"]
    F --> G["collapse slashes"]
    G --> H["collapse dots"]
    H --> I["strip leading/trailing hyphens"]
    I --> J["strip leading/trailing slashes"]
    J --> K{"leading/trailing dot?"}
    K -- "not stripped - bug" --> L["Output starts/ends with dot"]
    K -- "after fix" --> M["Clean branch name"]
    L --> N["git fails: fatal invalid reference"]
    M --> O["git checkout succeeds"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Raw user input] --> B["normalize NFD"]
    B --> C["remove combining marks"]
    C --> D["spaces/underscores to hyphen"]
    D --> E["remove invalid chars"]
    E --> F["collapse hyphens"]
    F --> G["collapse slashes"]
    G --> H["collapse dots"]
    H --> I["strip leading/trailing hyphens"]
    I --> J["strip leading/trailing slashes"]
    J --> K{"leading/trailing dot?"}
    K -- "not stripped - bug" --> L["Output starts/ends with dot"]
    K -- "after fix" --> M["Clean branch name"]
    L --> N["git fails: fatal invalid reference"]
    M --> O["git checkout succeeds"]
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
lib/branch-name.ts:14-16
Leading and trailing dots survive sanitization, and git's `check-ref-format` unconditionally rejects any ref whose name starts or ends with `.`. For example, the input `.feature` passes every existing replace step unchanged and produces an invalid branch name. The same applies to `feature.` (e.g., from a user typing `feature.` or from the removal of a trailing non-alphanum that happened to follow a dot). Adding a dot-trim step after the existing `-` and `/` trims closes the gap.

```suggestion
    .replace(/^-+|-+$/g, "")
    .replace(/^\/+|\/+$/g, "")
    .replace(/^\.+|\.+$/g, "");
}
```

Reviews (3): Last reviewed commit: "fix: handle multiple dots in path normal..." | Re-trigger Greptile

Comment thread scripts/cli.ts
Comment thread scripts/cli.ts Outdated
Comment thread lib/branch-name.ts
Comment thread GIT Command Generator.html
@MusicMaster4 MusicMaster4 merged commit d94d5c3 into main Jul 10, 2026
2 checks passed
Comment thread lib/branch-name.ts
Comment on lines +14 to +16
.replace(/^-+|-+$/g, "")
.replace(/^\/+|\/+$/g, "");
} No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Leading and trailing dots survive sanitization, and git's check-ref-format unconditionally rejects any ref whose name starts or ends with .. For example, the input .feature passes every existing replace step unchanged and produces an invalid branch name. The same applies to feature. (e.g., from a user typing feature. or from the removal of a trailing non-alphanum that happened to follow a dot). Adding a dot-trim step after the existing - and / trims closes the gap.

Suggested change
.replace(/^-+|-+$/g, "")
.replace(/^\/+|\/+$/g, "");
}
.replace(/^-+|-+$/g, "")
.replace(/^\/+|\/+$/g, "")
.replace(/^\.+|\.+$/g, "");
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/branch-name.ts
Line: 14-16

Comment:
Leading and trailing dots survive sanitization, and git's `check-ref-format` unconditionally rejects any ref whose name starts or ends with `.`. For example, the input `.feature` passes every existing replace step unchanged and produces an invalid branch name. The same applies to `feature.` (e.g., from a user typing `feature.` or from the removal of a trailing non-alphanum that happened to follow a dot). Adding a dot-trim step after the existing `-` and `/` trims closes the gap.

```suggestion
    .replace(/^-+|-+$/g, "")
    .replace(/^\/+|\/+$/g, "")
    .replace(/^\.+|\.+$/g, "");
}
```

How can I resolve this? If you propose a fix, please make it concise.

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