Skip to content

fix: refuse to remove a worktree with live processes - #44

Merged
liogi merged 3 commits into
mainfrom
fix/rm-refuses-live-worktree
Sep 14, 2026
Merged

liogi merged 3 commits into
mainfrom
fix/rm-refuses-live-worktree

Conversation

@liogi

@liogi liogi commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Trois défauts trouvés en utilisant l'outil, pas en le relisant. Tous les trois dans des commandes quotidiennes.

1. gwt rm pouvait à moitié supprimer un worktree — et ne savait plus finir

Avec des serveurs de dev encore vivants, git worktree remove supprime les fichiers pendant que les processus en réécrivent. Le rmdir final échoue, mais git a déjà désenregistré le worktree. La commande relancée répond alors :

No worktree matching 'test/cold-start'.

et le dossier à moitié vidé ne peut plus être nettoyé que par un rm -rf manuel.

Observé en conditions réelles : 51 processus vivants, 144 Ko d'orphelins laissés sur le disque — dont le CLAUDE.md et l'eslint.config.mjs du dépôt.

Correctif. rm cherche d'abord les processus tournant sous le worktree. Dans un terminal il les nomme et propose de les arrêter (SIGTERM, puis SIGKILL pour les récalcitrants) ; sans terminal il refuse et affiche le pkill à lancer.

--force ne l'outrepasse pas volontairement : il veut dire « l'arbre est sale et je le sais », pas « supprime les fichiers sous un serveur qui tourne ». C'est précisément avec --force que le dégât s'est produit.

La détection passe par pgrep -f sur le chemin du worktree — un serveur démarré là porte le chemin dans son argv. Le motif est échappé pour l'ERE, sans quoi un worktree release/1.0.0 matcherait des chemins qui ne sont pas les siens.

2. Une branche créée avec --from héritait de la base comme upstream

git worktree add -b fix/x <path> origin/main configure origin/main en upstream. Un git push nu échoue alors ainsi :

fatal: The upstream branch of your current branch does not match
the name of your current branch.  To push to the upstream branch
on the remote, use

    git push origin HEAD:main

Copiez cette suggestion un après-midi de fatigue et le correctif atterrit sur la branche par défaut. Sur un flux de tickets de support, c'est inacceptable.

--from passe maintenant --no-track, et le même git push suggère git push --set-upstream origin fix/x.

3. --from partait d'une base périmée

add ne faisait un fetch que si la branche existait déjà :

if (branchAlreadyExists) {
  log.step("Fetching latest changes from remote…");
  fetchBranch(branch);
}

Donc --from main sur une branche neuve utilisait la ref locale telle quelle — potentiellement vieille de plusieurs semaines, sans un mot. Le nouveau fetchBase rafraîchit la contrepartie distante, et quand une base locale est en retard sur son remote il dit de combien de commits et suggère --from origin/<base>.

Tests

172 tests (+7). Chacun vérifié rouge sans son correctif, en neutralisant l'appel dans le build :

not ok 1 - leaves the new branch without an upstream
not ok 3 - fetches the base, so the worktree starts from the remote's tip
not ok 1 - refuses without a terminal, and --force does not override it

Le test du fetch fait pousser un commit par un second clone entre-temps, puis vérifie qu'il est bien dans le worktree créé — c'est la course réelle, pas une simulation.

@liogi
liogi merged commit 8817256 into main Sep 14, 2026
2 checks passed
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.

1 participant