Repository navigation
feat: add remote_repo variable - #3745
Conversation
worktrunk-bot
left a comment
There was a problem hiding this comment.
Both sites that populate owner — build_hook_context and UserConfig::format_path — are updated, so the changelog's "available everywhere owner is" holds; GitRemoteUrl::repo() already strips .git in split_namespace_repo, and REPO_VARS, the help table, and the generated doc mirrors all move together.
On the name you asked about: remote_repo reads well beside the existing remote and remote_url, and the prefix is what disambiguates it from repo (the directory on disk), so I'd keep it. Worth an explicit call from @max-sixty before it ships, though — template variable names are part of the config surface, so renaming after a release is a break.
max-sixty
left a comment
There was a problem hiding this comment.
@canac thanks, very reasonable!
@worktrunk-bot please resolve conflicts
|
|
||
| ### Improved | ||
|
|
||
| - **`remote_repo` names the repository the way the remote spells it**: Templates had `owner` for the namespace in the primary remote URL but nothing for the repo name that follows it, so anything wanting the forge's name for the repository had to settle for `repo` — the directory on disk, which differs whenever a clone was renamed locally (`git clone git@github.com:company-org/project.git work` gives `repo = work`). `{{ remote_repo }}` resolves to the URL's repo component with the `.git` suffix stripped (`project`), and is available everywhere `owner` is: hook and alias bodies, `--execute` payloads, `wt step eval`, and the `worktree-path` template. Like `owner`, it is set only when a primary remote exists and its URL parses, so a template that must survive a remote-less repo guards it with `{% if remote_repo %}`. |
There was a problem hiding this comment.
De-slopped in 62b11b2 — 131 words down to 47.
What went: the worked git clone … work example, the enumeration of every scope the variable reaches (hook and alias bodies, --execute, wt step eval, worktree-path), the .git-stripping mechanic, and the {% if remote_repo %} guard. The release skill puts a non-headline bullet at 40 words or under and says to leave the "why it works this way" detail in the PR description, which is where all of that now lives.
What stayed: the contrast with repo that motivates the variable, and the unset-without-a-remote caveat, since that one changes how a template gets written.
- **`remote_repo` names the repository as the remote spells it**: `repo` is the directory on disk, so a renamed clone reports the new name. `{{ remote_repo }}` takes it from the primary remote's URL, available everywhere `owner` is and unset when no remote parses. ([#3745](https://github.com/max-sixty/worktrunk/pull/3745), thanks @canac)
Also added the PR link and the thanks @canac credit — the release skill asks for both on an external contribution, and every 0.72.0 bullet carries them.
# Conflicts: # CHANGELOG.md
Cut the entry from 131 words to ~47, within the release skill's 40-word ceiling for a non-headline bullet, and add the PR link and contributor credit the skill requires for external contributions.
|
Conflicts resolved in 9009e1c (merge of Only The snapshots were the thing worth checking, since All required checks are green on 62b11b2's predecessor and re-running now, including VerificationRun locally against the merge commit before pushing: CI on the merge commit 9009e1c: |
worktrunk 0.74.0
Created-by: HarmonybrewBot
Commit-by: HarmonybrewBot
Merged-by: HarmonybrewBot
Description: Created by `brew bump`
---
Created with `brew bump-formula-pr`.<details>
<summary>release notes</summary>
<pre>## Release Notes
### Improved
- **A JSON bool or null nested in a `vars` value renders as `True`, `False`, or `None`**: minijinja 2.22 adopted Jinja2's spelling for all three, so `{{ vars.<key>.<field> }}` into an object set by `wt config state vars set` prints those words. A var whose whole value is `true` stays a string. (Breaking: the old spellings were `true`, `false`, and `none`.) ([#3795](max-sixty/worktrunk#3795))
- **`wt config approvals add --yes` records approvals without a terminal**: the command refused every non-interactive run, so a container or CI job could not pre-approve a project it had just cloned. `--yes` now lists what it trusts and writes it, and a save it cannot make fails the command rather than warning and exiting 0. ([#3819](max-sixty/worktrunk#3819))
- **`remote_repo` names the repository as the remote spells it**: `repo` is the directory on disk, so a renamed clone reports the new name. `{{ remote_repo }}` takes it from the primary remote's URL, available everywhere `owner` is and unset when no remote parses. ([#3745](max-sixty/worktrunk#3745), thanks @canac)
### Fixed
- **`wt remove --force` deleted a live worktree moved onto another's registered path**: the ownership gate asked which *repository* the occupant belonged to, which a sibling worktree of this repo satisfies, so the directory went to trash with its uncommitted work. The directory and the registration must now name each other, as `git worktree remove` requires. Also reaches `wt merge`, `wt step prune`, and picker removal, and refuses a bare repository's path that `--force` previously deleted. ([#3808](max-sixty/worktrunk#3808))
- **`wt step copy-ignored` skips a source file that vanishes mid-copy**: the walk collects leaves, then copies them in parallel, so a file removed in between — a concurrent build rewriting `target/`, say — aborted the batch, under `--force` after deleting the destination. The source is stat'd before anything is removed now. ([#3744](max-sixty/worktrunk#3744), fixes [#3743](max-sixty/worktrunk#3743), thanks @dataders for reporting and fixing)
- **`wt step promote` refuses to delete a source it did not fully copy**: across filesystems the move copies then deletes, and an entry with no copy — a socket or FIFO, or a file a concurrent build rewrote mid-walk — was deleted anyway. The copy now reports what it skipped, and a non-zero count fails the move. ([#3820](max-sixty/worktrunk#3820))
- **An `ssh://` remote's host comes from the authority, not a later path segment**: the search for the userinfo `@` covered the whole remainder, so `ssh://git@attacker.example/owner/repo@github.com/org/repo.git` resolved to `github.com` and borrowed that repository's approvals while git dialed the attacker. Every URL form now splits the authority first, so `@` in a namespace parses instead of being rejected. ([#3813](max-sixty/worktrunk#3813))
- **`WORKTRUNK_*` env vars and `--config-set` outrank a `[projects."…"]` entry**: layer and specificity resolved separately, so a project entry answered for the global key whichever layer set it — `WORKTRUNK_WORKTREE_PATH` could not override a project's `worktree-path`. Both invocation layers now apply at either scope, and the help text gained a precedence section. ([#3790](max-sixty/worktrunk#3790), fixes [#3788](max-sixty/worktrunk#3788), thanks @jeremy0dell for reporting)
- **Shell completions register under the `--cmd` name**: `wt config shell init zsh --cmd wot` renamed the wrapper, but clap emitted the registration under `wt`. Bash and zsh completed nothing and regenerated the script on every TAB, PowerShell registered the wrong command, and zsh's `compdef` handed worktrunk's completer to the other `wt`. ([#3817](max-sixty/worktrunk#3817), fixes [#3816](max-sixty/worktrunk#3816), thanks @sbarre for reporting)
### Documentation
- **The picker's `Alt-x` never forces**: the keybinding table read `Remove selected worktree/branch`, which sent a reader looking for a force-remove that isn't there. ([#3811](max-sixty/worktrunk#3811), raised in [#3809](max-sixty/worktrunk#3809), thanks @josh-burton)
### Internal
- **Library API rework** (Breaking library API): `GitError::WorktreePathNotOurs` gained an `occupant_registered_at` field, and `WorkingTree::ensure_belongs_to_repo` is now `ensure_holds_this_worktree`. ([#3808](max-sixty/worktrunk#3808))
## Install worktrunk 0.74.0
### Install prebuilt binaries via shell script
```sh
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-installer.sh | sh && wt config shell install
```
### Install prebuilt binaries via powershell script
```sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-installer.ps1 | iex"; git-wt config shell install
```
### Install prebuilt binaries via Homebrew
```sh
brew install worktrunk && wt config shell install
```
## Download worktrunk 0.74.0
| File | Platform | Checksum |
|--------|----------|----------|
| [worktrunk-aarch64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-aarch64-apple-darwin.tar.xz) | Apple Silicon macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-aarch64-apple-darwin.tar.xz.sha256) |
| [worktrunk-x86_64-apple-darwin.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-x86_64-apple-darwin.tar.xz) | Intel macOS | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-x86_64-apple-darwin.tar.xz.sha256) |
| [worktrunk-x86_64-pc-windows-msvc.zip](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-x86_64-pc-windows-msvc.zip) | x64 Windows | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-x86_64-pc-windows-msvc.zip.sha256) |
| [worktrunk-aarch64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-aarch64-unknown-linux-musl.tar.xz) | ARM64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-aarch64-unknown-linux-musl.tar.xz.sha256) |
| [worktrunk-x86_64-unknown-linux-musl.tar.xz](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-x86_64-unknown-linux-musl.tar.xz) | x64 MUSL Linux | [checksum](https://github.com/max-sixty/worktrunk/releases/download/v0.74.0/worktrunk-x86_64-unknown-linux-musl.tar.xz.sha256) |
### Install via Cargo
```sh
cargo install worktrunk && wt config shell install
```
### Install via Winget (Windows)
```sh
winget install max-sixty.worktrunk && git-wt config shell install
```
### Install via AUR (Arch Linux)
```sh
paru worktrunk-bin && wt config shell install
```
</pre>
<p>View the full release notes at <a href="https://github.com/max-sixty/worktrunk/releases/tag/v0.74.0">https://github.com/max-sixty/worktrunk/releases/tag/v0.74.0</a>.</p>
</details>
<hr>
See merge request: Harmonybrew/homebrew-core!16610
Add a
remote_repovariable that returns the repo name from the remote URL. Unlikerepo, it stays consistent even if the clone was renamed.Feel free to reject, or suggest other names for the variable. But this change would improve my workflow. I hope you don't mind my submitting a PR before opening an issue. Thanks for an amazing developer tool!
AI Disclosure 🤖: I used Claude Code to generate the changes, but reviewed every line and made adjustments.