Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/hook.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Hooks are shell commands that run at key points in the worktree lifecycle — au
| **merge** | `pre-merge` | `post-merge` |
| **remove** | `pre-remove` | `post-remove` |

`pre-*` hooks block — failure aborts the operation (except `pre-start`, which warns and continues). `post-*` hooks run in the background with output logged to `.git/wt/logs/{branch}-{source}-{hook}-{name}.log`. Use `-v` to see expanded command details for background hooks.
`pre-*` hooks block — failure aborts the operation. `post-*` hooks run in the background with output logged to `.git/wt/logs/{branch}-{source}-{hook}-{name}.log`. Use `-v` to see expanded command details for background hooks.

The most common starting point is `post-start` — it runs background tasks (dev servers, file copying, builds) when creating a worktree.

Expand Down
2 changes: 1 addition & 1 deletion skills/worktrunk/reference/hook.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Hooks are shell commands that run at key points in the worktree lifecycle — au
| **merge** | `pre-merge` | `post-merge` |
| **remove** | `pre-remove` | `post-remove` |

`pre-*` hooks block — failure aborts the operation (except `pre-start`, which warns and continues). `post-*` hooks run in the background with output logged to `.git/wt/logs/{branch}-{source}-{hook}-{name}.log`. Use `-v` to see expanded command details for background hooks.
`pre-*` hooks block — failure aborts the operation. `post-*` hooks run in the background with output logged to `.git/wt/logs/{branch}-{source}-{hook}-{name}.log`. Use `-v` to see expanded command details for background hooks.

The most common starting point is `post-start` — it runs background tasks (dev servers, file copying, builds) when creating a worktree.

Expand Down
2 changes: 1 addition & 1 deletion src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ Alias names that match a built-in step command (`commit`, `squash`, etc.) are sh
| **merge** | `pre-merge` | `post-merge` |
| **remove** | `pre-remove` | `post-remove` |

`pre-*` hooks block — failure aborts the operation (except `pre-start`, which warns and continues). `post-*` hooks run in the background with output logged to `.git/wt/logs/{branch}-{source}-{hook}-{name}.log`. Use `-v` to see expanded command details for background hooks.
`pre-*` hooks block — failure aborts the operation. `post-*` hooks run in the background with output logged to `.git/wt/logs/{branch}-{source}-{hook}-{name}.log`. Use `-v` to see expanded command details for background hooks.

The most common starting point is `post-start` — it runs background tasks (dev servers, file copying, builds) when creating a worktree.

Expand Down
2 changes: 1 addition & 1 deletion src/commands/worktree/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl<'a> CommandContext<'a> {
self,
HookType::PreStart,
extra_vars,
HookFailureStrategy::Warn,
HookFailureStrategy::FailFast,
None,
crate::output::post_hook_display_path(self.worktree_path),
)
Expand Down
2 changes: 1 addition & 1 deletion tests/integration_tests/post_start_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ approved-commands = ["exit 1"]
"#,
);

// Should show warning but continue (worktree should still be created)
// Failing pre-start hook (via deprecated post-create name) aborts with FailFast
snapshot_switch(
"post_create_failing_command",
&repo,
Expand Down
26 changes: 23 additions & 3 deletions tests/integration_tests/user_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,16 @@ failing = "exit 1"
"#,
);

Comment thread
worktrunk-bot marked this conversation as resolved.
// Failing user hook should produce warning but not block creation
// Failing pre-start hook (via deprecated post-create name) aborts with FailFast.
// The worktree is already created before pre-start runs (it was renamed from
// post-create), so the worktree exists but the command exits non-zero.
snapshot_switch("user_post_create_failure", &repo, &["--create", "feature"]);

// Worktree should still be created despite hook failure
// Worktree exists (created before pre-start ran) but the command failed
let worktree_path = repo.root_path().parent().unwrap().join("repo.feature");
assert!(
worktree_path.exists(),
"Worktree should be created even if post-create hook fails"
"Worktree should exist — it was created before pre-start ran"
);
}

Expand Down Expand Up @@ -1125,6 +1127,24 @@ fn test_standalone_hook_post_create(repo: TestRepo) {
assert!(content.contains("STANDALONE_POST_CREATE"));
}

#[rstest]
fn test_standalone_hook_pre_start_fails_on_failure(repo: TestRepo) {
// pre-start hooks use FailFast like all other pre-* hooks — consistent with
// the symmetric pre (blocking, fail-fast) / post (background, warn) pattern.
repo.write_project_config(r#"pre-start = "exit 1""#);

let output = repo
.wt_command()
.args(["hook", "pre-start", "--yes"])
.output()
.unwrap();

assert!(
!output.status.success(),
"wt hook pre-start should exit non-zero when the hook fails (fail-fast, like all pre-* hooks)"
);
}

#[rstest]
fn test_standalone_hook_post_start(repo: TestRepo) {
// Write project config with post-start hook
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,13 @@ info:
WORKTRUNK_TEST_SKIP_URL_HEALTH_CHECK: "1"
XDG_CONFIG_HOME: "[TEST_CONFIG_HOME]"
---
success: true
exit_code: 0
success: false
exit_code: 1
----- stdout -----

----- stderr -----
▲ Project config has deprecated settings. Run wt config show for details or wt config update to apply updates
◎ Running pre-start project hook @ _REPO_.feature
  exit 1
✗ Command failed: exit status: 1
✓ Created branch feature from main and worktree @ _REPO_.feature
↳ To customize worktree locations, run wt config create
▲ Cannot change directory — shell integration not installed
↳ To enable automatic cd, run wt config shell install
✗ pre-start command failed: exit status: 1
↳ To skip pre-start hooks, re-run with --no-verify
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,13 @@ info:
WORKTRUNK_TEST_SKIP_URL_HEALTH_CHECK: "1"
XDG_CONFIG_HOME: "[TEST_CONFIG_HOME]"
---
success: true
exit_code: 0
success: false
exit_code: 1
----- stdout -----

----- stderr -----
▲ User config has deprecated settings. Run wt config show for details or wt config update to apply updates
◎ Running pre-start user:failing @ _REPO_.feature
  exit 1
✗ Command failing failed: exit status: 1
✓ Created branch feature from main and worktree @ _REPO_.feature
↳ To customize worktree locations, run wt config create
▲ Cannot change directory — shell integration not installed
↳ To enable automatic cd, run wt config shell install
✗ pre-start command failed: failing: exit status: 1
↳ To skip pre-start hooks, re-run with --no-verify
Loading