Skip to content

feat: add remote_repo variable - #3745

Merged
max-sixty merged 4 commits into
max-sixty:mainfrom
canac:remote-repo-var
Aug 14, 2026
Merged

max-sixty merged 4 commits into
max-sixty:mainfrom
canac:remote-repo-var

Conversation

@canac

@canac canac commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Add a remote_repo variable that returns the repo name from the remote URL. Unlike repo, 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.

@worktrunk-bot worktrunk-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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 max-sixty left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@canac thanks, very reasonable!

@worktrunk-bot please resolve conflicts

Comment thread CHANGELOG.md Outdated

### 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 %}`.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@worktrunk-bot please de-slop

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

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.
@worktrunk-bot

Copy link
Copy Markdown
Collaborator

Conflicts resolved in 9009e1c (merge of main), and the changelog entry de-slopped in 62b11b2 — reply on that thread has the before/after.

Only CHANGELOG.md conflicted: 0.72.0 shipped while this branch was open, so the release consumed the ## Unreleased heading this entry was written under. Kept both — a fresh ## Unreleased holding the remote_repo bullet, above the released 0.72.0 section. Everything else merged clean, including src/cli/mod.rs and the help snapshots.

The snapshots were the thing worth checking, since main moved the help surface a fair amount in the meantime (schema v2, --print-schema, the color refactor in #3777). test_docs_are_in_sync and the 47 test_help* cases pass unchanged, so no regeneration was needed.

All required checks are green on 62b11b2's predecessor and re-running now, including codecov/patch. The only non-terminal check on the merge commit was affected tests (macos, advisory), which is advisory.

Verification

Run locally against the merge commit before pushing:

cargo build --tests                                          ok
cargo test --lib --bins                        1482 + 965 + 11 + 1 passed
cargo test --test integration test_docs_are_in_sync          ok
cargo test --test integration test_help                      47 passed
cargo test --test integration eval                           12 passed
cargo test --test integration -- step_alias user_hooks post_start_commands   238 passed

CI on the merge commit 9009e1c: test (linux), test (macos), test (windows), lint, fast-checks, check-docs, gate, review, codecov/patch, codecov/project all pass.

@max-sixty
max-sixty merged commit aa9d8c4 into max-sixty:main Aug 14, 2026
37 checks passed
social4hyq pushed a commit to social4hyq/homebrew-core that referenced this pull request Sep 20, 2026
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
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.

3 participants