worktrunk

max-sixty·max-sixty.worktrunk

A Git worktree manager for trunk-based development

worktrunk (wt) is a Git worktree manager designed for trunk-based development workflows. It simplifies creating, switching between, and managing Git worktrees, making it easy to work on multiple features or branches simultaneously without the overhead of stashing or switching branches in a single working directory.

winget install --id max-sixty.worktrunk --exact --source winget

Latest v0.70.0·July 29, 2026

Release Notes

Release Notes Improved

  • wt step prune removes worktrees far faster: Each removal ran a serial chain of ~17 git subprocesses under the scan write lock, re-preparing a plan the scan had already computed and re-stating the worktree right after the fsmonitor daemon stop. The chain is now one check per guarantee, reusing the scan-time plan, and removals run concurrently on the scan lock's read side — the write side is kept for the candidates that need it (hook-bearing, --foreground, metadata-pruning, and the current worktree). The documented rust-scale live prune of 24 candidates goes from ~12 s to ~0.6 s wall, and the prune_e2e/live benchmark from ~620 ms to ~400 ms. (#3617, #3631)
  • wt step prune --format=json is ordered, and a failed removal aborts the rest: Live JSON output is now sorted by scan index, matching --dry-run, with the current worktree last. The first failing removal drains the remaining queue unexecuted, matching the serial loop it replaced; in-flight removals complete. (#3631)
  • A worktree can be named by its path wherever a branch is accepted: Every argument that takes a branch now also accepts the worktree's own path, resolved after the branch so a directory never shadows a branch sharing its name. A path names what a branch cannot — a detached worktree, or one of two checkouts of the same branch. Relative paths resolve against -C and a leading ~ against the home directory, so a path worktrunk printed can be pasted back. Docs (#3607)
  • wt list flags a branch checked out in more than one worktree: Such a branch resolves to whichever worktree git lists first, so every worktree on it now carries ⚑ — worktree.state "duplicate_branch" in schema 1, a worktree.duplicate_branch boolean in schema 2. The flag makes the ambiguity visible in the listing; resolving such a branch from any command warns separately and names a duplicate to drop. (#3480, #3606)
  • wt switch --execute computes only the template variables its command names: The switch path built every variable the template context could hold before rendering; it now resolves just the ones the command references. On a clone with no origin/HEAD and no cached default branch, that removes a git ls-remote the command never asked for — 13 subprocesses and one remote query down to 8 and none. (#3628) Fixed
  • A branch checked out in a second worktree is retained on removal, -D included: wt remove and wt step prune now act on the worktree named rather than the branch's first checkout, and all three of wt remove, wt step prune, and wt merge keep the branch while another worktree still has it out — deleting the ref would leave that worktree unable to resolve HEAD, which is why git branch -d refuses the same delete. The retention is reported and names the surviving checkout rather than passing silently. (#3533)
  • Removal reports what it took, not what it selected: A removal's summary and JSON described the plan, so a worktree candidate whose branch was retained still counted as ✓ Pruned 1 branch, and wt remove --format=json reported "branch_deleted": true beside a stderr line saying the branch was kept. Execution now returns the branch's fate; wt step prune counts executed outcomes (--dry-run included), both JSON payloads gained branch_deleted, and a declined orphan deletion drops out of the removed list rather than being reported as removed. (#3633, #3637)
  • Hook previews expand every variable except vars.: One vars. token disabled expansion for the whole command, so wt hook show --expanded and wt hook --dry-run printed {{ branch }} and {{ repo }} raw in a listing whose job is to show the expansion. A preview now substitutes a stand-in that renders each vars. reference back as itself, nested access included, while every other variable expands — and no longer spawns the git read that resolving vars required. The listing is also derived from the execution path itself, so a context key added there reaches the preview with no second edit. wt config alias dry-run shares the renderer, so its help text — which still described the all-or-nothing behavior — was corrected to match. (#3635, #3638, #3639)
  • wt hook show no longer prints a bare heading for an empty command list: A hook type declared as post-switch = [] has a config entry but no commands, and the section decided it had printed something from the entry rather than from the rows — so it emitted its heading and stopped, and the (none configured) line never appeared. Both the user and project sections carried the bug, since the loop and the fallback were duplicated; they now share one renderer that reports whether it wrote any rows. The execution path was already correct: an empty list announces nothing and is omitted from JSON. (#3641)
  • wt config shell install reclaims its own legacy wrapper paths: Fish sources conf.d at startup, so a stale conf.d/{cmd}.fish was already loaded by the time fish would autoload the functions/{cmd}.fish the install had just written — the old definition won and the new wrapper never loaded. Install decided ownership by reading the file, and left anything unrecognized in place. Ownership now comes from the path: conf.d/{cmd}.fish and the stranded nushell {cmd}.nu candidates are paths worktrunk computes for the command being installed, so it takes them back whole, unread. Only that exact filename is touched — a neighbour under another name is not worktrunk's — and each removal is reported. wt config shell uninstall still reads the header, because it takes no --cmd and so cannot know the name; it prompts and previews every file first. (Breaking: install now removes a file at those exact paths regardless of its contents.) (#3602)
  • Command timeouts actually bound wall-clock, and a default branch guessed while the remote was unreachable isn't cached: A timeout killed only the direct child, so a surviving grandchild held the output pipe open and the call ran on regardless — a 3 s bound measured at 120 s. A timed command now runs in its own process group and the whole tree is torn down on expiry, which fixes every existing bound including the fsmonitor and reap probes. On top of that, nothing in git bounds git ls-remote (an unreachable host costs ~127 s per address on Linux), so default-branch detection abandons the query after 10 s and falls back to local inference — without caching the result, so an outage can't make an inferred default branch permanent. (Breaking: because a timed command gets its own process group, Ctrl-C no longer reaches it; the command waits out the remaining bound.) (#3603)
  • wt step relocate no longer strands a worktree in its staging directory: When worktree A's target was held by worktree B, and B was itself blocked by a non-worktree path without --clobber, the dependency loop read the stall as a cycle, temp-moved A into .git/wt/staging/relocate/, then failed moving it into the still-occupied target — leaving A at neither its original nor its expected path. A worktree blocked by an immovable occupant is now skipped. (#3530)
  • Forge CLI failures are classified by response shape, not by the tool's prose: tea api copies the response body to stdout and exits 0, so an HTTP error never tripped the exit-code gate — a Gitea APIError body deserialized into {state: "", total_count: 0}, indistinguishable from a commit with no CI statuses, while the PR-list path blamed an API change for what was an API error. Failures from gh, glab, and tea are now keyed on the response envelope, and a non-zero exit keeps meaning the tool itself failed; the CLI's own error text is forwarded rather than reworded, so a bad token surfaces as gh: Bad credentials (HTTP 401) instead of a suggestion to re-authenticate. wt config show --full reports the Azure DevOps CLI extension alongside the other forge tools. (#3595, #3597, #3605)
  • wt config plugins claude install-statusline no longer mistakes another tool's statusline for its own: The check for an existing worktrunk statusline matched the bare substring wt , which an unrelated command like newt status satisfies — so wt config show reported a foreign statusline as worktrunk's, and the installer early-returned "already configured" and refused to install. It now matches the adjacent list statusline token pair, so it works whether the binary is wt, git-wt, or an absolute path. (#3595)
  • [list] task-timeout-ms is removed: The per-command bound is gone; [list] timeout-ms bounds the whole collect phase. A config that still sets it warns, and wt config update strips the key — in the top-level, project-scoped, and inline-table forms. (Breaking: the setting no longer has any effect. It was also, until this release, ignored for a command that carried its own bound.) (#3613, #3615) Documentation
  • wt remove documents what retention protects: The branch-cleanup section's six conditions all ask whether deleting loses work; a branch checked out in a second worktree fails a different test, and the page now says so, alongside a new "Naming a worktree" section on wt switch. The FAQ's advice to git worktree lock a worktree holding precious ignored data now says what the lock actually buys — it blocks removal, and nothing else; wt merge and wt step push will still overwrite an ignored file the incoming commits track. (#3533, #3601, #3607)
  • Default-branch detection documents the remote-query bound: The detection ladder records that the git ls-remote step is abandoned after 10 s, that local inference covers the abandoned case, and that this is the one result not cached. (#3603)
  • wt step push records that destination-worktree safety matches git: Pushing overwrites an ignored file in the destination whose path the incoming commits track, exactly as a git merge run there would; the spec now says the match is deliberate. (#3614) Internal

Installer type: zip

x643D17E4AF5BF2E651ADE0E919296184A4664599C29EDC97BFF67D6DC3443DBA78

Details

Homepage
https://github.com/max-sixty/worktrunk
License
MIT OR Apache-2.0
Publisher
max-sixty
Support
https://github.com/max-sixty/worktrunk/issues

Tags

cligitgit-worktreerustterminalworktree

Older versions (114)

v0.69.2
x64C4343FB59D4938433A600AEB7A2AF52FED2E412889C6FA6788D74982C87A1A43
v0.69.1
x64ED84DF1942B0F78DC16CA774A72E351E0D4BA41B6D861AB95DFD9DCFB7EAC6ED
v0.69.0
x64E3B7A6BF623783DC35DD6C2BBAA42A59B4B3FCD91E9CB4F6F456DDFD26B47F1A
v0.68.0
x645201AAE6AACAE94F8E81D5D73A7B46150A0D46577A10EEF784C500E7724163CA
v0.67.0
x644A3AF596F0C2C6C7E3142EFD979ED7921441F163AE17C2F8F41E0D96051652F4
v0.66.0
x64C5C032CBF2B29950E23E777973DC65FBD77EA0463F1E2452360D8EFC74C3A43D
v0.65.0
x6411DA7702F84D1326B72E579EABE69376524CF8CD1FF113DA742D8730F8C61D49
v0.64.0
x64D56887E7B9933B9983EA4DE35195B9D2AE092D3EFBA028D4B6BC400D93169D2A
v0.63.0
x64CDB639184DB2FA606CB3BE65F6B84D399DC717CB637D104F2D151B79A78DA73D
v0.62.0
x643963112C4BE9DC16B0F9E2765D7C7E26E7CBB7804134957D90C759991B346562
v0.61.0
x64DFD658266E4B6A804546C42B0DF87AA18A2F6CFAFA7AE7297C3BA6C264C1ADB8
v0.60.0
x647F0F07BDD2BCFE9C5FAE68002024E77BDABC162B69913D501BF1E30A76E26318
v0.59.0
x64BBE76C2E721894F356C4C2F1524659D37E0228A969EDA71061CE26B08B2FC7FF
v0.58.0
x646FFB85A51C43E6FD6FD5B687D7E02CAAB85E1D2B716BEA8B068A845A14DBCBE1
v0.57.0
x644352650CB3DEFE6E9E4DA613089DA32E76BC3F947462B2950AEC8BCE5FC5940D
v0.56.0
x6424D081D482A4D3F23EF686EB1CFD4F0E74CD3D4FA2D577732785181EA9B72463
v0.55.0
x643D2D9BF5726448004E8B64982E5B8EDC77EEE555BFE10B7A1E3B14BFEAC64BE9
v0.54.0
x64D71BF401232ABBDC81B2635231A7DF71249DE08BDB10DE7F2A50C7FF748B22BF
v0.53.0
x64D33E0647D523B027E8DF9370391BFC4E696DBD2BC7E89B4CBCD1D6607445CF36
v0.52.0
x6415640D80678FAC8FCC1909E9FE8622EF4295929A09DC1C8CDC8CD53248880A98
v0.51.0
x641F06181A4B4999651F39EF270A8CDDCFB0C81D6A886A0AE2EAA9711C7743D5FC
v0.50.0
x64B0392619F50809D89A51B0EF7372B9820758BBE4C9A546089D6DE6DDB6DD0E3B
v0.49.0
x6479D706AE92A51DF75EB9014BE12D11AB1B9C4B7E5E561498D8396041C7B82F6B
v0.48.0
x6454B4741C8C8159D8ECDA25B4A22ADEA930DFA7EC50C7CA0A30ADB74B80220D5E
v0.47.0
x649C3C7D507629C1A06085978C66C05819BC3BC77291FE9101466755A216DE8077
v0.46.1
x6452A58A3E2D10D50DBF69577A2F737D167440CEC6A27F97F03A85D63BAF510C2B
v0.46.0
x647A97E9B89D464DC7D77731E634DEBC34B07935F2D7444831E9E9698829E682A5
v0.45.2
x6430B514CAD3946D459CD02E3BAFA058E8C1113ECC3C003CA5507481F3A9691C00
v0.45.1
x6423A718884AB4C397EDC3E25E8F6ED4903FABD093AA7A4E6702B0DF2A2831874D
v0.45.0
x645AACCF21F842E8E8E5DE71AB98F548CD72A28629EA7869826A5AD94AE4C95783
v0.44.0
x644E67790BB02CB690CCB42A53C2152022E959B2302FFD5F3C716C96E621B22FD6
v0.43.0
x64278DD7019D8D085E54582CF8D005EB8A9341F7FDDC7EDA0527CBE57A77EBA817
v0.42.0
x64E84B9CA923A2FFB53BE8465F5DD37C82283BAE95D030C0C864C0F250BE498258
v0.41.0
x649D6FD2319A36D6AC76288E4B72B91AA9D877EBBB8A567654CD7EA9D03A1F088C
v0.40.0
x6430A55E07707AB5E51260426E87704B78D26DE207AD74102DCC0C58FD61A71386
v0.39.0
x64EE57D931D3E3CDD420F82E79E7B47498973BC2B026BAE76A62F617EC46A328C4
v0.38.0
x642ED3AFD2AE4AC0603F83405B219D2B50C5C9605D677CC94D4286CA999DBF1612
v0.37.1
x642BC6EC34A03D76AD68512688E9FF44CFCCD8FA124BC47373E453FDA78BAF16E8
v0.37.0
x64A1898B865881345440D8EF714DCB40CBDA664A954517AF334BAFE9EF0EC8AA1F
v0.36.0
x645434D445A68FCF2D5771C6DC5AA137F13E4CBA1A6174C16A15029F4F51A9A9DF
v0.35.3
x649C038BBC46F52F890FF9DC17103D622E84C6FFAB161E624702C95CD853892275
v0.35.2
x643D2C66A25B87B6C72595FE67A20F76BEA117FB991855613280EC81DB0FD45A7B
v0.35.1
x648D97AC5DCF1AD126DF648009A5BC437B6D9D58749A0736F000BFC6CB330238D7
v0.35.0
x6400F5A50B10BB59F38CEA96F0CC61DBA58AEAADC722E046049E0D66F1A22F559D
v0.34.2
x64CBEFDB4F49088A95DCEC671B6879086F52D078414E91633C92EF8A8147916A30
v0.34.1
x649B8E216552B4C9894FA36CF91A1F225EC01511D5264BE79A00F6BC9D594F3B4A
v0.34.0
x649AD0C8740960EA25A290718961D9E942F24C2683FF35273A13C1B6EAA1B18A91
v0.33.0
x641093577AE40CF256F7646B2DAA81FBEA5CCF0542F31F74FEEC06480CD9415485
v0.32.0
x64C66C6E335B5458BE88A357C96FEC9B4EE2ACA596DC1DFF9E70C2BBE35403FEDA
v0.31.0
x6435F03FB8208ED68AA65231DDF1F726D76C37BDA8323DA61FB46468EC371F8EE4
v0.30.1
x648667F2B8CCF7BA0457105C09AF0ACB6962B176E53F96096D88DC428DB5490953
v0.30.0
x6458166B2B0C104ADE5E026C9D447A786F125F763E8D49979EEE537193F7556F04
v0.29.4
x6410885B58E677054E9FF867FCF9EEFDD6C6DECD0C7032B25ECC52DC5FA7559294
v0.29.3
x648EFFD9AE101FD934A45B8562B0FD0463E2E7E9A020971536A35E87A62DEF2E1B
v0.29.2
x640F49622EDF1409B606D08F6CD1BBF1D4F139A0DB106C6D816720C438E327B62E
v0.29.1
x64779D247EDBADCD31B5C4EF1E53E832876186FED96D701004B83C225D9123BF67
v0.29.0
x647761E312EE30543462606805F915083C3D2E855F6BF3F773062EB9112AB6213A
v0.28.2
x64FE68654726548EA30560518EE8168893A2D7B792CBDFBB718148AD95766883C9
v0.28.1
x643320A7A3FF485C37541636BC4149F2C1123B7361C1320C355E6B8D2B769D3474
v0.28.0
x648CB44BCF30B7B113A12382BD3002868657E29CA9DDF5F432BB84D28A82E0FA5F
v0.27.0
x64FCB8345FA85C6C12B4E1BF327AF832BA8460D65F177D684FF1C39A1AA95F0B81
v0.26.1
x64D393EFD1D965D3D13BFF52F5081D0C97A74AFB1CA3C8EF47E4D1C879F8E6B711
v0.26.0
x6476A39C52B51A0055CB723784E3BFF1432E20F6533A3A7886196E7B63F846031A
v0.25.0
x64038146BEE263A49B3CC15BE65C96FC400B8C465A85899421B5E3C0E634014BC8
v0.24.1
x64DBAA1435AF9CCD7B3D302F534F6983DC7854AF66703B3E2C7735A7B24D0B32CF
v0.24.0
x64460515A71EE617789FB95ABB7083BDA79FE8BD99CB144DCD25CED36153EBA6CC
v0.23.3
x6440CF9944D0A27E802FEF2AD0F90BC48256AE54CFB936174109589D9838F3F3F8
v0.23.2
x64DB9A732337BD855BF567450CC38B312A3428E19FFFB2283E7FB7E9793437E3A5
v0.23.1
x64E9577875C4E96196BA105D927F0A1312FDB59095E07824ED7F1F813C4F6E4458
v0.23.0
x6498BFD7F9BEEC23C7F4D7E044A65869B65E202260402D55A3D0847EB46D920606
v0.22.0
x64B9A7F5C027BF9B9AC0B21A31E4D6BDEBE3B3C193170CA6A5FAA6AA91F1C791E6
v0.21.0
x646D2BA343879CAA4D196A657C9AE53691E1D2740B5B6E62A0E08058955A50578D
v0.20.3
x64CCA65CEDB3F7F2E8B33BD4B65A200336C3B4679415872697007C118A0A26C4E0
v0.20.2
x643ABB4C5A6A30B6A3E78F5D79E99ED811D06C911AAB24EC529F08490A1FE27C18
v0.20.1
x64EDD48775E18B5087138AF987DAA667C2482142D585490176ACEA396BB45B5CCF
v0.20.0
x64B7988FDF636540D25061CA8CE74D1D6EE3BAACE57AE21077E9180CA9E0C7459F
v0.19.0
x64888247185DFB38448275EB072421BC0F2F4828184994BEFAAB2A24AB2A838308
v0.18.2
x640CA0D0133A55DD584F7A309C3425BAF6DC748EB5373AAA9CE5133AC8175C1142
v0.18.1
x6437803531F6028E25617B5FBF31E4CEB25D795B27A258E1D79D8FE72EDA5DDFCF
v0.18.0
x6459CD8BBB93E470B7FF3846BAB74C8C901687685FF1F2D32D084D3419FA8C0BC7
v0.17.0
x641D4CE38DE691AB75530CCA87AF1316D20EDC3A0086E4E01FC4512A9401B4674D
v0.16.0
x6489648F3C50E754F1222E36C852A8CA31C38B19930701BA8599469D91BEBCF059
v0.15.5
x64460BE4BB222E1AC0A0BA41D8F5A337E39697666CE3FA0EC716A0F0385ABB4068
v0.15.4
x643034B6C0958A0F9F58C90C13B4AF68B0FD9AF312BC20C4E412DDACEFD08EB4CD
v0.15.3
x64A427DB19FDA4811FFED96E91EC8101F566AE82BC58156326E54F935BC00D7D71
v0.15.2
x64688DCBB16EAF2683470505EBCEBDD72E9906CC257EF822C198BEC680F187F635
v0.15.1
x64AA29555A8D18FAAEAA8041CBE2D251D43DF14BD6005C2C323AE6A5BB7EF59872
v0.15.0
x644765CB5833406DF80821D6D0F2DACA4746A52603EF750ECB94711016E1D2E732
v0.14.2
x6468BAC63D9716F2846379EE88E3AB8AAA02AE2BF20572230B25E34839F9CD4857
v0.14.1
x6427D21CB998150BC49EB0BDCA5C39C055AB1CC8700050493CED26A484871378B2
v0.14.0
x64876B574422D306C8BBF91594B10C03C42BC9BAA64242BC4BC3D1B9EC73B6F1A3
v0.13.4
x647ADBD17F794E506572B8D5497F5216C0772C058649A2E370C88145BB434A341E
v0.13.2
x646D6703C513D0D9980450AC4F5BC26C235C1808E51AC89E72412C9728015D8CBE
v0.13.1
x64AB83AEED65F24BA76494B3C1ED099F6F3F2B772CD7BCC5B86CF7AFD7E05E6BBE
v0.13.0
x641C0B097D25323BC216E2457ED121F2576831F2367DD267814B6DD8FF96B87573
v0.12.0
x6473F5DABE030D30C44E6B1CCFAF89BA8750399E3D997B428A54F1015824744348
v0.11.0
x64B1E9B676AFBE602C6A5DA8BB7D56C95B64ACA90B626F86041E2328C955D6FB0A
v0.10.0
x648CBCFC131C4CAC5D7004D0B41064D67444C035A46C8D41577FF0BACA4C6FA540
v0.9.5
x64B2C5911A56B43A5E96F90249AAE0F37EEF37F429A379C267F7B9AF24A105C11A
v0.9.4
x646B9F56DE80236432A31255E621993257D9D2F1E86B03472377C19FF758F17F49
v0.9.3
x64B6B740D22C91FCC52215898C7101B42EE0BC948C9C7C007AFDBFFCDC20487BB0
v0.9.2
x648D4C2ED16D6410CA55BD1317BBFEE9EA486BB3A142C8DB52AF9B427BB94657C3
v0.9.1
x64DB7160F54177BD3A25007E4CB104A79D60F45809A384D5C16220FD3B58C5FDE1
v0.9.0
x641F3FC58A3E4706C395E7918614D7F788D5CF1233285F9C5B9029AEA1EA009403
v0.8.5
x64712A402D3C6E719F62AED67E630754C3B45CCC01C34A66FD9FEF70D5EF104F22
v0.8.4
x6481274C119FAF5B15FB6349EBD4F2DDB4DD4A9AE7993B9D7FE91B5FADDF34CCAE
v0.8.3
x64AC39CB749D58770EAAD7C9F74CFA7721C44956124E832CB2BB776ED64F0B2FBF
v0.8.1
x6483413D5A2DFC6DCD304DB5ED53AAB4FB2AAE387570754A39B5055F39C6A0E64D
v0.7.0
x6480A111959A87A60A388E027DDF5B27198F093FF5CDFCBE08FDD261A0C0EC5DD1
v0.6.1
x640161E6B7EEDDE8B2F028D6D70C0B29E744CDDA26716E89EAEDC5A1858BAC241E
v0.6.0
x64999B7D3CE6D0609394135B916B36285A3C7A13232CF0834E1EFFF3063182E703
v0.5.2
x64373A4CADCF4C3E03AD67BDB8CC95C83B8579681A9960B098205CA67A6867A8A8
v0.5.1
x64101F4B5C663D13810889C8A042B11583EAEA5075B92BC8F7BB19864AA087AF38
0.5.0
x643188C8464234EC4BE89D773353170479C55708BBEF8BB977184DD7B8B5EC0609