Repository navigation
fix(git): detached HEAD, tag-shadowed branches, submodule worktrees and wide PR titles - #679
Open
eric-engberg wants to merge 4 commits into
Open
eric-engberg wants to merge 4 commits into
eric-engberg wants to merge 4 commits into
Conversation
On a detached HEAD (a tag checkout, a rebase in progress, a bisect), `git symbolic-ref` fails, so Git Branch showed "no git" (or hid itself with hide-no-git) inside a perfectly good work tree. It now shows the short commit in parentheses, as git prompts do, e.g. "⎇ (0449a12)", and the repo link points at that commit. When a tag has the same name as the current branch, `symbolic-ref --short` disambiguates the name to "heads/<branch>", so the widget showed "⎇ heads/release" and linked to .../tree/heads/release. It now reads the full ref and strips "refs/heads/", which is always the plain branch name.
…rate git dirs Git Worktree decided "main worktree" by the git dir's path: ".git" at the end, else a ".../worktrees/<name>" pattern. A submodule's git dir is .git/modules/<name> and a --separate-git-dir repo's is wherever it was put (e.g. /x/repo.git), so both showed "no git". The path pattern could also misread a repo kept under a directory named "worktrees". It now asks git for both the git dir and the common dir in one call. A linked worktree's git dir is always <common dir>/worktrees/<name>; any other git dir belongs to the main worktree.
PR titles were cut with title.slice(0, 29), counting UTF-16 code units.
An emoji at the cut lost its second half and showed as U+FFFD ("�"), and
a CJK title passed the 30-unit limit while taking 59 columns, since each
character is two columns wide.
Truncation now goes through the same display-cluster and width logic
the renderer uses for max widths, keeping the 30-column limit and the
single "…" ellipsis.
A plain replaceAll says what the line does without a global regex.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
⎇ (0449a12), instead of⎇ no git. With hide-no-git on, it no longer disappears. The repo link points at that commit.⎇ releaseinstead of⎇ heads/release, and links to…/tree/releaseinstead of…/tree/heads/release.--separate-git-dirrepo shows𖠰 maininstead of𖠰 no git.�, and a CJK title is cut to the same 30 columns as any other instead of taking 59.Why
git symbolic-ref --short HEAD, which fails when HEAD isn't on a branch:--shortdisambiguates the name when a tag has it too, so it isn't a branch name any more:.gitat the end means main,…/worktrees/<name>means linked, anything else means "no git". A submodule's git dir is.git/modules/<name>, and a--separate-git-dirrepo's is wherever it was put:worktrees, e.g.~/worktrees/app/.git/modules/libshowed asapp/.git/modules/lib.truncateTitleusedtitle.slice(0, 29), which counts UTF-16 code units.Update the release workflow 🚀 for tagged buildskept the first half of the rocket's surrogate pair, which prints as U+FFFD.修复状态栏在窄终端下的显示问题并且添加更多的测试用例以及文档说明kept 29 characters, 58 columns wide.How
git symbolic-ref HEADand stripsrefs/heads/, which always leaves the plain branch name. (git branch --show-currentwould also work, but needs git 2.22.) When there's no branch, it falls back togit rev-parse --short HEAD, the lookup Git SHA already makes, so the two share the git cache entry.no git(or hiding it) now only happens outside a work tree or when both lookups fail. A normal branch renders and links exactly as before. The detached link uses/tree/<sha>, which GitHub and GitLab both resolve.git rev-parse --git-dir --git-common-dirin the one call it already made. A linked worktree's git dir is always<common dir>/worktrees/<name>, so that's the only shape read as linked, and the name is what follows. Any other git dir is the main worktree's. Linked worktrees keep their names, including those of bare repos, submodules and separate-git-dir repos. In a subdirectory of the main worktree, git prints the git dir absolute and the common dir relative (../../.git), and that still reads as main. Git older than 2.5, which has no--git-common-diror linked worktrees, reads as main too.truncateStyledText, the display-cluster and width logic the renderer already uses for max widths, to 29 columns, then adds the same single…. Titles of plain ASCII come out exactly as before.Demo
The status line piped from sample repositories built for the demo (fake remotes, PR data from a pre-filled cache, nothing fetched), with Git Branch, Git Worktree and Git PR on one line: a tag checkout, a branch with a tag of the same name, a submodule, and two long PR titles.
Powerline: before
Powerline: after
Plain: before
Plain: after
Testing
mainfirst: Git Branch on a detached HEAD (text, hide-no-git, link) and with a tag of the same name; Git Worktree in a submodule, a submodule under aworktreesdirectory, and a separate git dir; Git PR titles with an emoji at the cut and in CJK. Also added: main from a subdirectory of the main worktree, and a CJK title that fits. The existing Git Branch and Git Worktree tests now mock git's real output for the new commands.bun test: 2792 pass, 0 fail.bun run lintpasses.main).mainonly as shown above. The baseline line is unchanged, and the TUI opens and exits cleanly under both.