Conflict probe: orphaned merge-tree processes and lost results with expensive merge drivers; no way to skip it in picker/JSON

Open
#4,585 1 comment 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
git, rust

Research direction

Start with compute_merge_tree_outcome in src/git/repository/integration.rs, then trace probe cancellation in src/shell_exec.rs and task planning in src/commands/list/collect/mod.rs and src/commands/picker/mod.rs. Review #4274 and the related issues to understand the existing trade-offs. Done means the probe lifecycle and an opt-out for the picker and JSON address the reported behavior; the issue also asks whether preview probes should ignore configured merge drivers.

Written by the indexing model from the issue text.

Description

Setup

  • worktrunk v0.81.0, git with merge-tree --write-tree, macOS.
  • One repository with about 285 linked worktrees.
  • A global attributes file (core.attributesFile) sets *.json merge=mergiraf, a structural merge driver. The repo contains roughly 205 generated JSON catalogues of about 2.2 MB each, so a branch that touches them sends all of them through the driver.

Observed

The conflict probe is git merge-tree --write-tree <target> <branch> (compute_merge_tree_outcome, src/git/repository/integration.rs), run once per worktree. With the default of 32 concurrent commands (WORKTRUNK_MAX_CONCURRENT_COMMANDS), wt list, the wt switch picker and the integration probe in wt remove/wt merge can start many of these at once.

  1. Probes outlive wt. Since #4274 the probe is finish_once_started(), so cancel_background_commands() (src/shell_exec.rs) no longer signals it. When the picker exits, or wt list is interrupted before it finishes, the running git merge-tree processes are reparented to PID 1 and run to completion. With slow merge drivers that is tens of seconds of CPU each, and with 285 worktrees it is a large number of processes.
  2. Their results are discarded. The persistent cache write (sha_cache::put_merge_conflicts in run_merge_tree) happens in the wt process that spawned the probe. After wt exits, nothing reads the orphan's output, so the work is lost. The next invocation recomputes it, so repeated picker use never converges. #4274 mentions this trade-off; the cost is much larger with an expensive driver.
  3. The probe cannot be switched off for the picker or JSON. [list] columns narrows the task plan for the table (required_tasks_for_render), but --format json always plans all_columns and the picker always runs the full task set (comments in src/commands/list/collect/mod.rs and src/commands/picker/mod.rs). The Status column pulls in MergeTreeConflicts, so there is no way to keep the status column and skip the probe.

Numbers

One probe on a branch that touches the catalogues (git merge-tree --write-tree <target> <branch>):

attributes source wall/CPU peak RSS
global merge=mergiraf 42 s CPU 741 MB
GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=core.attributesFile GIT_CONFIG_VALUE_0=/dev/null 2.6 s CPU 603 MB

The result still reports conflicts either way (50 vs 48 conflicted files), so the probe answers its question without the driver. The repository's own .gitattributes still applies under the override. Mergiraf can resolve some conflicts that text merge cannot, so this is only acceptable for a preview, not for real merges.

Asks

a. A config setting and/or flag to skip the conflict probe (or the whole MergeTreeConflicts task), honoured by the picker and by --format json, not only by the table's [list] columns.
b. Either persist results from probes that outlive wt (for example have the probe process write its own cache entry), or bound them with a deadline that kills the process and cleans up its .merge_file_* temp files.
c. Optionally run preview probes with a wt-controlled attribute source (for example a GIT_CONFIG_* override of core.attributesFile, or git --attr-source), so user-configured expensive merge drivers are skipped for previews only.

Workaround

A wrapper script ahead of wt on PATH that, for the probe-heavy subcommands only, sets WORKTRUNK_MAX_CONCURRENT_COMMANDS=8 and exports the GIT_CONFIG_* override above. Scripts that only need a branch-to-path map avoid wt list and use git worktree list --porcelain instead. This works but is easy to miss, and it disables custom attribute drivers for everything wt runs under it.

Related: #4273 (closed by #4274), #3883.

🤖 Generated with Claude Code

Dominant language
Rust
Stars
8.8k
Forks
315
Avg merge
1d 6h
Merged PRs (30d)
204

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from max-sixty/worktrunk

All issues in max-sixty/worktrunk

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.