---
title: Référence des sous-commandes
description: Chaque sous-commande `gwm` avec sa synopsis, ses flags, ses codes de sortie et des exemples.
---
# Référence des sous-commandes
`gwm <subcommand>` est la face scriptable de gwm. Chaque commande se termine avec un code significatif (`0` ok, `1` avertissement, `2` échec), de sorte que vous pouvez brancher `gwm doctor` dans la CI sans parser la sortie standard.
`gwm` seul (sans sous-commande) ouvre le [TUI](/fr/tui) sur le dépôt courant.
## `gwm init [--preset <name>] [--list-presets] [--show]`
Écrit un `.gwm.toml` dans le dépôt courant — le template générique documenté par défaut, ou un preset de stack opinionné.
```bash
gwm init
# → wrote /path/to/repo/.gwm.toml
gwm init --preset rust # seed a Rust-flavoured .gwm.toml
gwm init --list-presets # enumerate the built-ins, write nothing
gwm init --preset node --show # print the resolved TOML, write nothing
```
Refuse d'écraser un `.gwm.toml` existant. Ajustez le fichier généré et relancez `gwm doctor` pour le valider.
| Flag | Action |
|:------------------|:------------------------------------------------------------------------------------------------|
| `--preset <NAME>` | Initialise un `.gwm.toml` opinionné pour une stack connue au lieu du template générique (issue #37) |
| `--list-presets` | Liste les presets intégrés avec une description d'une ligne et quitte (n'écrit rien, ne nécessite pas de dépôt git) |
| `--show` | Affiche le preset (ou le template) résolu sur stdout au lieu de l'écrire — pratique pour differ |
### Presets de stack (issue #37)
`--preset <name>` initialise un `.gwm.toml` opinionné pour une stack connue au lieu du template générique — copies d'env, invariants no-symlink et la bonne commande d'install pré-câblés. `gwm init --list-presets` les énumère :
```text
generic The fully-documented default template (same as `gwm init`).
go Go module: bin/ no-symlink + `go mod download`.
laravel Laravel: env copies + AWS-RDS guard + vendor/ no-symlink + composer install.
node Node / Nuxt: node_modules/ no-symlink + bun-or-npm install. (alias: nuxt)
python-uv Python (uv): .venv/ no-symlink + `uv sync`.
rust Rust crate: target/ no-symlink + `cargo fetch`.
```
`nuxt` est un alias de `node` (même corps), et `generic` est le défaut documenté — `gwm init` sans flag l'écrit à l'octet près. Les corps des presets sont embarqués dans le binaire et tenus synchronisés avec [`examples/presets/<name>.toml`](https://github.com/kbrdn1/gwm-cli/tree/main/examples/presets). `--show` affiche le TOML résolu sur stdout sans toucher au disque, vous pouvez donc differ un preset contre une config existante :
```bash
gwm init --preset laravel --show | diff - .gwm.toml
```
## `gwm config`
Lire, éditer et valider `.gwm.toml` sans ouvrir le fichier à la main.
```bash
gwm config get tui.confirm_countdown_secs
gwm config set tui.confirm_countdown_secs 5
gwm config set 'labels[+].name=bug'
gwm config unset review.tool
gwm config list --prefix worktree
gwm config validate
vi "$(gwm config path)"
gwm config edit
```
Les clés utilisent la notation par chemin pointé. Les tables de tableau utilisent des index (`labels[0].name`), et `set` accepte aussi `[+]` pour ajouter l'entrée de table suivante. Les écritures utilisent `toml_edit`, donc les commentaires et le formatage existants sont préservés ; après chaque écriture, gwm recharge le même schéma d'exécution que celui utilisé par le reste de la CLI.
## `gwm types [--gitmoji]`
Liste les types de branche pris en charge (l'emplacement `<type>` de `gwm create`).
```bash
gwm types
# → feat
# fix
# hotfix
# docs
# …
gwm types --gitmoji
# → feat ✨ :sparkles:
# fix 🐛 :bug:
# …
```
Surchargez par dépôt via `[worktree].branch_types` dans `.gwm.toml`.
| Flag | Action |
|:-------------|:--------------------------------------------------------------------------------------------------|
| `--gitmoji` | Étend la liste avec deux colonnes — l'emoji unicode et sa forme `:shortcode:` (issue #85) |
`--gitmoji` résout l'emoji de chaque type à partir des valeurs par défaut intégrées plus tout override `[gitmoji]` propre au dépôt dans `.gwm.toml`. Les types de branche personnalisés sont pris en charge — `migration = ":truck:"` fait un aller-retour à travers `gwm types --gitmoji`. Voir [`gwm commit-prefix`](#gwm-commit-prefix---branch-name---unicode) pour la surface commit-prefix correspondante.
## `gwm commit-prefix [--branch <name>] [--unicode]`
Affiche le préfixe canonique Gitmoji + Conventional Commits pour la branche courante (ou nommée) — pratique pour les prompts de shell, les assistants IA et la composition scriptée de commits.
```bash
gwm commit-prefix
# → :sparkles: feat(#41):
gwm commit-prefix --unicode
# → ✨ feat(#41):
gwm commit-prefix --branch feat/#41-tui-search
# → :sparkles: feat(#41):
```
Sans `--branch`, lit la branche courante depuis `HEAD` via libgit2 (nécessite que le CWD soit à l'intérieur d'un dépôt git). `--branch` résout le préfixe pour un nom de branche explicite ; il lit tout de même `.gwm.toml` pour les overrides `[gitmoji]`.
| Flag | Action |
|:-----------------|:---------------------------------------------------------------------------------------------------------|
| `--branch <name>`| Résout le préfixe pour une branche nommée (par ex. `feat/#41-tui-search`) au lieu de `HEAD` |
| `--unicode` | Émet le vrai caractère emoji (`✨`) au lieu de la forme `:shortcode:` (`:sparkles:`) |
Sous `--unicode`, les overrides `:shortcode:` connus sont normalisés vers leur emoji (par ex. un `[gitmoji]` `feat = ":rocket:"` affiche `🚀 feat(#1):`) ; les shortcodes inconnus passent tels quels — pas de panique, pas de substitution. Le mapping des emoji est la valeur par défaut intégrée plus tout override `[gitmoji]` dans `.gwm.toml`.
## `gwm hooks install commit-msg [--force]`
Installe un hook git `commit-msg` opt-in qui ajoute automatiquement en tête le préfixe de commit résolu quand un message n'en commence pas déjà par un.
```bash
gwm hooks install commit-msg # install into .git/hooks/commit-msg
gwm hooks install commit-msg --force # overwrite an existing commit-msg hook
```
Le hook n'est **jamais installé implicitement** — vous l'activez une fois par dépôt. Il est non destructif par défaut : il refuse d'écraser un hook `commit-msg` préexistant (husky / commitlint / pre-commit) et se termine avec un code non nul en indiquant le chemin en conflit, sauf si `--force` est passé. Le hook respecte `core.hooksPath`, résout le fichier `.git` d'un worktree lié via `Repository::discover`, et se dégrade proprement si `gwm` n'est pas sur le `$PATH` au moment du commit (le message est laissé intact). `commit-msg` est aujourd'hui le seul type de hook ; clap rejette toute autre valeur au moment du parsing.
| Flag | Action |
|:------------|:-----------------------------------------------------------------------------|
| `--force` | Remplace un hook existant du même nom (sinon l'installation refuse) |
Le préfixe qu'il ajoute est exactement ce que [`gwm commit-prefix`](#gwm-commit-prefix---branch-name---unicode) affiche pour la branche du worktree.
## `gwm create <type> <issue> <desc>`
Crée un worktree et la branche correspondante.
```bash
gwm create feat 123 user-authentication
# → branch feat/#123-user-authentication
# → worktree ~/cc-worktree/<repo>/feat-123-user-authentication
gwm create feat 123 foo --no-bootstrap # skip the bootstrap pipeline
```
| Flag | Action |
|:------------------------|:--------------------------------------------------------------------------------------------|
| `--no-bootstrap` | Saute les étapes de bootstrap de `.gwm.toml` (copies / guards / commands / hooks) |
| `--reuse-branch` | Se rattache à une branche locale existante du même nom au lieu de refuser (issue #99) |
| `--skip-hooks <PHASES>` | Saute les phases de hook de cycle de vie séparées par des virgules (par ex. `pre_create,post_create`) |
| `--repo <NAME>` | En [mode workspace](#mode-workspace-global---workspace-issue-36), quel dépôt enfant reçoit le worktree — requis là pour lever l'ambiguïté ; ignoré en mode mono-dépôt (issue #36) |
Par défaut `gwm create` refuse de réutiliser silencieusement une branche locale obsolète — il se termine par une erreur nommant le tip obsolète pour que vous puissiez l'auditer ; `--reuse-branch` est l'échappatoire opt-in.
Le déroulé de bout en bout vit dans [Premiers pas → Premier worktree](/fr/getting-started/first-worktree).
## `gwm new <type> <desc>`
Crée une issue GitHub à partir du formulaire d'issue configuré du dépôt, puis crée le worktree correspondant à partir du numéro d'issue retourné.
```bash
gwm new feat add-config-types
# → created issue #142 [Feature]: add-config-types
# → branch feat/#142-add-config-types
```
`gwm new` lit `[issue_template]` depuis `.gwm.toml`, rend le fichier `.github/ISSUE_TEMPLATE/*.yml` sélectionné en markdown, appelle `gh issue create --body-file`, puis passe la main au même chemin de création de worktree que `gwm create`.
| Flag | Action |
|:-----------------|:--------------------------------------------------------------------|
| `--no-bootstrap` | Crée le worktree sans lancer le bootstrap |
| `--reuse-branch` | Se rattache à une branche locale existante après la création de l'issue |
| `--skip-hooks` | Saute les phases de hook de cycle de vie séparées par des virgules |
## `gwm review <PR#> [--name <branch>] [--bootstrap] [--skip-hooks <phases>]` (issue #308)
Matérialise une PR GitHub existante dans un worktree isolé — récupère le head de la PR, attache un worktree, lie la PR, et vous reviewez le code du contributeur en quelques secondes.
```bash
gwm review 310 # fetch PR #310 into review/pr-310-<author>-<slug>
gwm review 310 --name pr-310 # override the local review branch name
gwm review 310 --bootstrap # ...and run bootstrap + lifecycle hooks (opt-in)
```
`gwm review` résout le head de la PR via `gh` et récupère la ref universelle `refs/pull/<N>/head` d'origin, il est donc **conscient des forks croisés** et valide pour des PR dans n'importe quel état (open / draft / closed / merged). Il crée une branche locale `review/pr-<N>-<author>-<slug>`, attache un worktree (le répertoire est dérivé du nom de branche, les slashes deviennent des tirets), et lie la PR pour que la [barre latérale / l'indicateur CI du TUI](/fr/tui) s'allument immédiatement. Démontez comme n'importe quel worktree : `gwm remove <dir> --delete-branch`.
| Flag | Action |
|:------------------------|:---------------------------------------------------------------------------------------------|
| `--name <BRANCH>` | Surcharge le nom de la branche de review locale (défaut `review/pr-<N>-<author>-<slug>`) ; le répertoire du worktree en est dérivé |
| `--bootstrap` | Lance bootstrap + hooks de cycle de vie contre le code de la PR après création (désactivé par défaut) |
| `--skip-hooks <PHASES>` | Saute les phases de hook de cycle de vie séparées par des virgules (par ex. `pre_create,post_create`) |
**Sûr par défaut :** le bootstrap et les hooks de cycle de vie ne sont **pas** lancés. Un worktree de review contient le code d'un contributeur (possiblement issu d'un fork), et ces étapes exécutent des commandes contre lui (`npm install`, `composer install`, `direnv allow`, hooks `post_create` …) — c'est-à-dire du code arbitraire. Passez `--bootstrap` pour l'activer une fois que vous faites assez confiance à la PR pour la mettre en place. C'est distinct du bloc de config `[review]` (qui pilote la touche lanceur de review `R` du TUI) ; `gwm review` est la sous-commande de matérialisation de worktree.
## `gwm pr [--draft] [--base <ref>] [--render]`
Rend le corps de la PR depuis `[pr_template]` et délègue à `gh pr create` contre le tronc résolu.
```bash
gwm pr # creates the PR
gwm pr --draft # creates a draft PR
gwm pr --base develop # diff against develop instead of [doctor].trunks
gwm pr --render # prints the rendered body to stdout (no PR created)
gwm pr --render | gh pr create --body-file -
```
`gwm pr` lit la branche courante (en parsant `<type>/#<N>-<desc>` pour les placeholders `{type}` / `{issue}` / `{desc}`), choisit le premier tronc existant de `[doctor].trunks` (ou retombe sur `main`), puis rend le template par type de branche sous `[pr_template.by_type.<type>]` (le `body` inline l'emporte sur `path`), avec `[pr_template].default` comme repli.
| Flag | Action |
|:--------------------|:--------------------------------------------------------------------|
| `--render` | Affiche le Markdown rendu sur stdout ; ne délègue jamais à `gh` |
| `--draft` | Transmet `--draft` à `gh pr create` pour que la PR s'ouvre en brouillon |
| `--base <REF>` | Surcharge la base de comparaison au lieu du premier tronc correspondant |
En cas de succès, le numéro de la nouvelle PR est enregistré sous `branch.<head>.gwm-pr` (la même clé que `gwm link pr` écrit), donc `gwm status` et `gwm open pr` résolvent le lien sans appel `gwm link` séparé.
La résolution du corps et la sémantique des placeholders sont documentées sous [Configuration → `[pr_template]`](/fr/configuration/gwm-toml#pr_template-issue-84).
## `gwm list [--format=table|names|json] [--detect-pr] [--workspace <dir>]`
Liste les worktrees du dépôt courant.
```bash
gwm list # human-readable table
gwm list --format=names # one worktree name per line (for shell completion)
gwm list --format=json # machine-readable JSON array (issue #38)
gwm list --detect-pr # add a PR column, auto-detecting each branch's PR via gh
gwm list --workspace ~/Projects # merged table across every child repo, leading REPO column
```
Le format `names` exclut le workdir principal — `gwm path / remove / bootstrap` ne l'acceptent jamais comme cible, donc l'émettre comme candidat de complétion serait trompeur.
`--format=json` (issue #38) émet un tableau JSON stable — schéma documenté à [`docs/schema/worktree-list.schema.json`](https://github.com/kbrdn1/gwm-cli/blob/main/docs/schema/worktree-list.schema.json). Contrairement à `names`, il **inclut** le worktree principal : un consommateur JSON (un éditeur, une barre de statut) veut l'ensemble complet et y résout le worktree actif. Chaque entrée porte `name`, `id`, `path`, `branch`, `head`, `is_main` / `is_locked` / `is_prunable`, un objet `status` (`is_dirty`, `has_upstream`, `ahead`, `behind`, `unknown`), `age_seconds`, et les numéros `issue` / `pr` liés. À piper dans `jq` :
```bash
gwm list --format=json | jq '.[] | select(.status.is_dirty) | .name'
```
`--detect-pr` ajoute une colonne `PR` peuplée par la [détection automatique de PR](/fr/integrations/github-linking#détection-automatique) (`gh pr list --head <branch>` par worktree). Elle est **désactivée par défaut** pour que le listing simple reste sans réseau — un appel `gh` par worktree n'est payé que lorsque le flag est posé. Ignorée avec `--format=names`.
`--workspace <dir>` (issue #36) affiche la table de worktrees fusionnée sur chaque dépôt git situé un niveau sous `<dir>`, avec une colonne **REPO** en tête nommant le dépôt de chaque ligne. Voir [Mode workspace](#mode-workspace-global---workspace-issue-36) pour le comportement complet.
## `gwm path <pattern> [--format=text|json]` (alias : `gwm cd <pattern>`)
Affiche le chemin sur disque d'un worktree correspondant à `<pattern>` (fuzzy). À utiliser avec `$(...)` pour faire `cd` :
```bash
cd "$(gwm path auth)"
cd "$(gwm cd auth)" # same — framing for the cd flow
gwm path auth --format=json # { "name": ..., "path": ..., "branch": ... }
```
La forme `text` par défaut affiche le chemin nu pour la consommation `$(...)`. `--format=json` (issue #38) émet le triplet `{ name, path, branch }` — schéma à [`docs/schema/path.schema.json`](https://github.com/kbrdn1/gwm-cli/blob/main/docs/schema/path.schema.json).
Les deux formes partagent la sémantique : résolution fuzzy, sortie `0` sur une correspondance unique, `1` sur un échec / une ambiguïté / hors d'un dépôt. À associer à `gwm shell-init` pour le one-liner `gcd` — voir [Premiers pas → Shell init](/fr/getting-started/shell-init).
## `gwm switch` (alias : `gwm s`)
Ouvre le TUI en **mode sélecteur** — la même table que `gwm` seul, la barre de filtre fuzzy pré-ouverte, create / delete / bootstrap désactivés. Appuyez sur `Enter` pour afficher le chemin du worktree surligné sur stdout, `Esc` / `q` / `Ctrl-C` pour annuler avec le code de sortie `1`.
```bash
cd "$(gwm switch)" # open picker, type to narrow, Enter to commit
gcd # same, via the `gwm shell-init` wrapper
```
## `gwm bootstrap [<pattern>]`
Relance le pipeline de bootstrap de `.gwm.toml` sur un worktree sans le recréer.
```bash
gwm bootstrap # on the CWD worktree
gwm bootstrap auth # on a fuzzy-matched name
```
Utile après avoir édité `.gwm.toml` ou ajouté de nouvelles règles `[[bootstrap.copy]]`. Même rapport `✓ / ! / ✗` que `gwm create`.
| Flag | Action |
|:------------------------|:--------------------------------------------------------------------------------|
| `--skip-hooks <PHASES>` | Saute les phases de hook de cycle de vie séparées par des virgules (par ex. `pre_bootstrap,post_bootstrap`) |
## `gwm sync [<pattern>] [--merge]`
Récupère l'upstream d'un worktree et met sa branche à jour — rebase par défaut, ou merge avec `--merge`.
```bash
gwm sync # the CWD worktree, rebase onto upstream
gwm sync auth # a fuzzy-matched worktree
gwm sync auth --merge # merge the upstream instead of rebasing
```
Résout la cible comme `gwm bootstrap` (motif fuzzy, par défaut le worktree contenant le CWD — qui peut être le worktree principal, vous pouvez donc aussi synchroniser le tronc). Il lance `git fetch` pour le remote de l'upstream, recalcule le retard de la branche, puis n'intègre que lorsqu'il y a quelque chose à intégrer. Rapporte une seule ligne `✓` (`already up to date` / `rebased N commit(s)` / `merged N commit(s)`).
Garde-fous :
- **Arbre de travail sale** → refuse avant de toucher au remote (`commit or stash`). Un rebase/merge par-dessus du travail non commité est la façon de perdre des changements.
- **Aucun upstream configuré** → erreur avec le correctif `git branch --set-upstream-to=<remote>/<branch>`.
- **Conflit** → le rebase/merge est **abandonné** pour que le worktree reste utilisable, et on vous indique de réconcilier à la main.
Les étapes fetch / rebase / merge délèguent à votre `git` (donc les clés SSH, les credential helpers et les règles `insteadOf` s'appliquent toutes) ; l'inspection sale / upstream / avance-retard utilise libgit2.
## `gwm remove <pattern> [--delete-branch] [--dry-run]`
Supprime un worktree par correspondance fuzzy. La branche survit par défaut.
```bash
gwm remove auth # remove the worktree, keep the branch
gwm remove auth --delete-branch # remove the worktree AND drop the branch
gwm remove auth --dry-run # preview the plan, destroy nothing
gwm remove auth --dry-run --delete-branch # preview, including the branch drop
```
La forme CLI n'a pas de compte à rebours (le [compte à rebours de l'overlay de confirmation `d`](/fr/tui/confirm-countdown) du TUI est propre au TUI). `--delete-branch` est destructif — seul `git reflog` peut ressusciter une branche supprimée.
| Flag | Action |
|:-------------------|:------------------------------------------------------------------------------------------------------------|
| `--delete-branch` | Supprime aussi la branche locale après avoir retiré le worktree (destructif) |
| `--dry-run` | Affiche le plan de suppression (nom + chemin + branche) et sort `0` sans rien toucher (issue #31) |
| `--force` | Mode de suppression d'urgence : saute les [hooks de cycle de vie](/fr/configuration/gwm-toml) `pre_remove` / `post_remove` |
| `--skip-hooks <PHASES>` | Saute les phases de hook de cycle de vie séparées par des virgules (par ex. `pre_remove,post_remove`) |
`--dry-run` résout le motif fuzzy, affiche le plan et sort `0` — aucune destruction, **aucune écriture dans le journal** (voir [`gwm undo` / `gwm history`](#gwm-undo---bootstrap)). Avec `--delete-branch`, il marque la ligne de branche `(would be deleted)` ; sur un worktree en detached-HEAD il affiche `branch: - (no branch to delete)` à la place, reflétant le comportement du chemin destructif. Un motif ambigu déclenche la même erreur de liste de candidats avec code non nul que la forme destructive — `--dry-run` ne supprime que la destruction, pas les échecs de résolution.
## `gwm prune [--dry-run]`
Efface les entrées obsolètes dans `.git/worktrees/` dont le répertoire de travail a été supprimé manuellement (par ex. `rm -rf` en dehors de gwm).
```bash
gwm prune # prune every stale entry
gwm prune --dry-run # list the prunable entries, touch nothing
```
`gwm doctor` signale les entrées élaguables comme un Warning ; `gwm prune` est la remédiation documentée.
| Flag | Action |
|:-------------|:----------------------------------------------------------------------------------------------------|
| `--dry-run` | Liste chaque entrée élaguable (nom + chemin + raison) et sort `0` sans toucher aux fichiers d'admin (issue #31) |
La sortie de `--dry-run` est triée par nom pour un diff de stdout déterministe ; le cas vide affiche `0 worktree(s) to prune` pour que les appelants scriptés obtiennent un signal stable. Les largeurs de colonne sont calculées en caractères Unicode pour que les noms non-ASCII restent alignés. L'aperçu et la passe destructive partagent le même scanner, donc ils ne peuvent jamais diverger sur la définition de « élaguable ».
## `gwm undo [--bootstrap]`
Récupère d'un `gwm remove` raté sans archéologie de `git reflog`. Dépile l'opération destructive la plus récente enregistrée pour le dépôt courant, recrée `refs/heads/<branch>` à l'OID sauvegardé, et réajoute le worktree au chemin sauvegardé (avec `reuse_branch` pour que la branche ressuscitée s'attache proprement).
```bash
gwm undo # bring back the last removed worktree + branch
gwm undo --bootstrap # ...and re-run the per-worktree bootstrap
```
| Flag | Action |
|:---------------|:--------------------------------------------------------------------------------|
| `--bootstrap` | Relance le bootstrap par worktree après la résurrection (désactivé par défaut) |
L'entrée du journal n'est consommée **qu'après** une résurrection réussie — un échec en cours de route laisse l'ancre de récupération intacte pour que vous puissiez réessayer. Une entrée en detached-HEAD (aucune branche à recréer) est refusée avec une erreur explicite plutôt que de ne rien faire silencieusement. Le journal est partagé avec [`gwm history`](#gwm-history---limit-n---all) ; voyez-le pour l'emplacement du fichier et la politique de rotation.
## `gwm history [--limit N] [--all]`
Liste les opérations destructives récentes enregistrées par gwm, les plus récentes en premier.
```bash
gwm history # last 20 ops for the current repo
gwm history --limit 50 # last 50
gwm history --all # every op across every repo (forensic / multi-repo)
```
| Flag | Action |
|:---------------|:-----------------------------------------------------------------------------------------|
| `--limit N` | Nombre maximum d'entrées à afficher, les plus récentes en premier. Défaut `20` |
| `--all` | Liste les opérations de tous les dépôts, pas seulement le courant |
Par défaut il filtre sur le workdir canonicalisé du dépôt courant ; `--all` fait remonter chaque entrée. Un résultat vide affiche `no operations recorded` comme signal scripté stable. Le journal vit à `$XDG_DATA_HOME/gwm/history.toml` (à surcharger avec `$GWM_HISTORY_FILE` ; macOS retombe sous `Application Support`, Windows sous `%LOCALAPPDATA%`) et est plafonné à 100 entrées — la plus ancienne est supprimée en cas de débordement. Chaque `gwm remove` (avec ou sans `--delete-branch`) ajoute une entrée ; `gwm remove --dry-run` n'écrit **pas** dans le journal, donc prévisualiser une destruction ne peut jamais vous laisser « annuler » quelque chose qui n'a jamais eu lieu.
## `gwm completions <shell>`
Affiche un script de complétion statique. Shells pris en charge : `zsh`, `bash`, `fish`, `powershell`, `elvish`. Voir [Complétions de shell](/fr/cli/completions) pour l'installation par shell.
## `gwm shell-init <shell>`
Affiche le wrapper de shell `gcd`. Shells pris en charge : `zsh`, `bash`, `fish`, `powershell`. Voir [Premiers pas → Shell init](/fr/getting-started/shell-init).
## `gwm tmux <pattern> [-p|--split]`
Ouvre le worktree correspondant dans une nouvelle fenêtre tmux de la session **courante**. `--split` substitue `split-window` à `new-window`. Nécessite que `$TMUX` soit défini.
```bash
gwm tmux auth # new tmux window inside the matched worktree
gwm tmux auth -p # split the current pane instead
```
En dehors d'une session tmux, sort avec un code non nul et une erreur claire (ne lance pas de serveur orphelin).
## `gwm zellij <pattern> [-p|--split]`
Comme `gwm tmux` mais pour zellij. Utilise `zellij action new-tab --cwd <path>` (nécessite zellij ≥ 0.40 pour le flag `--cwd`) ou `new-pane --cwd` avec `-p`. Nécessite `$ZELLIJ`.
Voir [CLI → Intégration multiplexeur](/fr/cli/multiplexer) pour la surface complète et les cas limites.
## `gwm link {issue|pr} <N> [--worktree <pattern>]`
Lie le worktree courant (ou nommé) à une issue ou une PR GitHub.
```bash
gwm link issue 42 # link the current worktree to issue #42
gwm link pr 61 # link a PR
gwm link issue 42 --worktree feat-auth # ...or to a fuzzy-matched worktree
```
Le lien est stocké dans `git config branch.<name>.gwm-issue` / `gwm-pr` — local, par branche, aucun fichier supplémentaire. Les numéros d'issue sont **détectés automatiquement** depuis les branches `<type>/#<N>-<slug>`, donc `gwm link issue <N>` n'est nécessaire que pour les overrides explicites. Les numéros de PR ne sont pas détectés automatiquement.
## `gwm unlink {issue|pr} [--worktree <pattern>]`
Supprime l'override de lien explicite sur le worktree courant (ou nommé).
```bash
gwm unlink issue # remove the issue link (auto-detect resurfaces)
gwm unlink pr # remove the PR link
```
Idempotent — sûr à exécuter quand rien n'est lié.
## `gwm open {issue|pr} [--worktree <pattern>] [--print-url]`
Ouvre l'issue / PR liée dans le navigateur via l'ouvreur de l'OS.
```bash
gwm open issue # spawn the OS opener on the linked issue URL
gwm open pr --print-url # print the URL on stdout, no spawn
```
Utile dans les shells headless et les tests avec `--print-url`.
## `gwm status [--worktree <pattern>] [--json]`
Affiche le lien plus (quand `gh` est disponible) l'état GitHub en direct.
```bash
gwm status
# → Issue #42 [open] TUI: fuzzy search
# → PR #61 [draft] · checks 2/3
gwm status --json # stable schema for scripts
```
Se dégrade proprement vers une sortie lien-local-uniquement quand `gh` manque ou que le dépôt n'a pas de remote GitHub.
## `gwm labels {list|push}`
Gère l'ensemble déclaratif de labels GitHub depuis `.gwm.toml`. Déclarez une fois les labels que vous voulez dans `[[labels]]`, poussez-les vers le remote `origin` upstream au besoin — plus de dérive entre dépôts. Sans bloc `[[labels]]` dans `.gwm.toml`, les deux sous-commandes sont des no-ops (`0 labels declared, nothing to push`) et ne délèguent jamais à `gh`.
```bash
gwm labels list # show the diff against the remote
gwm labels push # apply create + update
gwm labels push --dry-run # plan only, no remote mutations
gwm labels push --prune # also delete labels not in config
gwm labels push --random-colors # random pastel for entries with no `color`
```
| Flag | Action |
|:-----------------|:------------------------------------------------------------------------------------------------------------------------------------------------|
| `--dry-run` | Affiche le plan sans muter le remote. Lit tout de même les labels distants via `gh label list` pour calculer le diff ; seuls les appels create / update / delete sont sautés. |
| `--prune` | Supprime sur le remote les labels non déclarés dans `.gwm.toml` (destructif — opt-in) |
| `--random-colors`| Utilise un pastel aléatoire pour les entrées sans champ `color` (surcharge le hash déterministe) |
Les sigils de sortie de `list` reflètent les groupes de diff :
```
+ bug (will create — color #d73a4a)
~ good first issue (color #008672 → #7057ff)
= documentation (match)
- wontfix (on remote, not in config)
```
Nécessite `gh` sur le `$PATH` (la même dépendance souple que `gwm status`). Référence du schéma et conseils de rédaction : [Configuration → `.gwm.toml`](/fr/configuration/gwm-toml#labels-issue-81).
## `gwm milestones {list|push}`
Gère l'ensemble déclaratif de milestones GitHub depuis `.gwm.toml`. Même forme que `gwm labels` ; l'endpoint REST est utilisé parce que `gh` n'a pas de sous-commande `gh milestone` native. Sans bloc `[[milestones]]` dans `.gwm.toml`, les deux sous-commandes sont des no-ops (`0 milestones declared, nothing to push`) et ne délèguent jamais à `gh`.
```bash
gwm milestones list # show the diff against the remote
gwm milestones push # apply create + update
gwm milestones push --dry-run # plan only, no remote mutations
gwm milestones push --prune # also delete milestones not in config
```
| Flag | Action |
|:------------|:----------------------------------------------------------------------------------------------------------------------------------------------------|
| `--dry-run` | Affiche le plan sans muter le remote. Lit tout de même les milestones distants via `gh api …/milestones` pour calculer le diff ; seuls les appels create / update / delete sont sautés. |
| `--prune` | Supprime sur le remote les milestones non déclarés dans `.gwm.toml` (destructif — opt-in) |
Les sigils de sortie de `list` reflètent les groupes de diff :
```
+ v0.7.0 (will create — state open, due 2026-07-15T23:59:59Z)
~ v0.6.0 (due 2026-07-01T23:59:59Z → 2026-07-15T23:59:59Z)
= v0.5.0 (match)
- old-sprint (#3 on remote, not in config)
```
Nécessite `gh` sur le `$PATH`. Référence du schéma et conseils de rédaction : [Configuration → `.gwm.toml`](/fr/configuration/gwm-toml#milestones-issue-82).
## `gwm doctor [--format=text|json]`
Lance 8 vérifications de santé ; rapporte chacune avec `✓ / ! / ✗` ; sort `0 / 1 / 2`. Conçu pour la CI et les hooks de pre-commit. Voir [Intégrations → `gwm doctor`](/fr/integrations/doctor) pour le détail par vérification.
`--format=json` (issue #38) émet le tableau de vérifications plus les agrégats `severity` et `exit_code` — schéma à [`docs/schema/doctor.schema.json`](https://github.com/kbrdn1/gwm-cli/blob/main/docs/schema/doctor.schema.json). Le **code de sortie du processus est identique** à la forme texte (le JSON le porte aussi comme champ), donc `gwm doctor --format=json` fonctionne toujours dans un garde `if` :
```bash
gwm doctor --format=json | jq '.checks[] | select(.status == "failed")'
```
## `gwm daemon [--socket <path>] [--poll-ms <ms>]` (issue #38)
Lance gwm comme **daemon JSON-RPC 2.0** au long cours sur une socket de domaine unix, pour que les éditeurs / barres de statut / outillages se connectent une fois au lieu de lancer `gwm` à chaque requête.
```bash
gwm daemon # bind $XDG_RUNTIME_DIR/gwm.sock (→ $TMPDIR → /tmp)
gwm daemon --socket /tmp/gwm.sock # explicit socket path
gwm daemon --poll-ms 500 # faster subscribe push, more git scans
```
**Format de fil :** JSON délimité par des retours à la ligne (NDJSON) — un objet requête par ligne, une réponse par ligne.
| Méthode | Params | Résultat |
|--------|--------|--------|
| `list` | — | tableau de worktrees ([schéma](https://github.com/kbrdn1/gwm-cli/blob/main/docs/schema/worktree-list.schema.json)) |
| `doctor` | — | rapport doctor ([schéma](https://github.com/kbrdn1/gwm-cli/blob/main/docs/schema/doctor.schema.json)) |
| `path` | `{ "pattern": "<str>" }` | `{ name, path, branch }` ([schéma](https://github.com/kbrdn1/gwm-cli/blob/main/docs/schema/path.schema.json)) |
| `subscribe` | — | flux de notifications `worktrees.changed` (la première = snapshot courant) |
```bash
# request/response (one line in, one line out)
printf '{"jsonrpc":"2.0","method":"list","id":1}\n' | nc -U "${XDG_RUNTIME_DIR:-${TMPDIR:-/tmp}}/gwm.sock"
```
`subscribe` transforme la connexion en flux de push à sens unique : le daemon envoie une notification `worktrees.changed` avec le snapshot courant, puis une à chaque changement. La détection de changement est un **polling à intervalle** de l'ensemble des worktrees (réglé par `--poll-ms`, défaut `1000`) — un choix MVP délibéré plutôt qu'une surveillance du système de fichiers, pour qu'il n'y ait pas de dépendance supplémentaire et que le comportement soit déterministe ; la latence de mise à jour est bornée par l'intervalle de polling.
**Plateforme / build :** Unix uniquement, derrière la feature Cargo `daemon` activée par défaut. Sous Windows ou un build `--no-default-features`, la sous-commande quitte avec une erreur explicative (elle reste listée pour que `--help` soit identique partout).
`--poll-ms` doit être `≥ 1` (`0` est rejeté — il ferait tourner la boucle `subscribe` sans attente, re-scannant git aussi vite que le CPU le permet).
## `gwm statusline [--socket <path>] [--watch]` (issue #309)
Affiche un résumé compact des worktrees sur une seule ligne pour un prompt shell — le premier **consommateur** embarqué de `gwm daemon`. Il se connecte à la socket du daemon, demande l'ensemble des worktrees, et rend la branche active, le nombre de worktrees, l'état dirty / ahead / behind, et l'issue / la PR liées.
```bash
gwm statusline # one-shot, affiche une ligne et quitte
gwm statusline --watch # subscribe ; ré-affiche à chaque changement
gwm statusline --socket /tmp/gwm.sock # socket du daemon explicite
```
```text
feat/#309-daemon-consumer · 3 wt · * ↑1 · #309 · PR #310
```
Jetons : branche (ou nom du worktree si HEAD détachée), compteur `N wt`, `*` dirty, `↑n`/`↓n` ahead/behind, `#N` issue, `PR #N`. Le worktree **actif** est celui qui englobe le répertoire courant ; hors de tout worktree, seul le compteur est affiché. Un rollup CI n'est volontairement pas inclus (il ne fait pas partie du schéma stable du daemon).
**Dégradation gracieuse :** quand aucun daemon n'est joignable, `gwm statusline` affiche une ligne vide et quitte avec `0`, pour qu'une substitution de prompt se réduise à rien au lieu d'échouer. Même résolution de `--socket` que `gwm daemon`. Voir [Intégrations → Consommateurs du daemon](/fr/integrations/daemon-consumers) pour les recettes de prompt (zsh / tmux / starship) et une recette éditeur (Zed / VS Code).
## Mode workspace (global `--workspace`) (issue #36)
`--workspace <dir>` est un flag **global** (`global = true`, donc accepté avant *ou* après la sous-commande) qui opère sur chaque dépôt git situé un niveau sous `<dir>` au lieu d'un dépôt unique. C'est une dimension orthogonale par-dessus le mode mono-dépôt.
```bash
gwm --workspace ~/Projects # open the TUI over every direct-child repo
gwm list --workspace ~/Projects # merged worktree table, leading REPO column
gwm --workspace ~/Projects list # same — the global flag may precede the subcommand
gwm --workspace ~/Projects create feat 12 search --repo my-api # disambiguate the target
gwm exec --workspace ~/Projects -- git fetch # fan out across every child repo's worktrees
gwm clean --workspace ~/Projects --yes # reclaim artifacts across every child repo
```
- **Le TUI / `gwm list`** gagnent une colonne **REPO** en tête nommant le dépôt de chaque ligne. Dans le TUI, le dépôt actif suit la sélection, donc chaque action pilotée par la sélection (lazygit, terminal, sync, delete, link, open, …) opère sur le dépôt propre au worktree surligné.
- **`gwm create`** en mode workspace requiert `--repo <name>` pour lever l'ambiguïté sur le dépôt enfant qui reçoit le nouveau worktree ; un nom absent ou inconnu liste les candidats.
- **`gwm exec` / `gwm clean`** (issue #326) se déploient (fan-out) sur chaque dépôt enfant. La commande / le jeu de répertoires de chaque dépôt est résolu en amont (un `--profile` manquant, un `[exec]`/`[clean]` malformé, ou un dépôt enfant inouvrable échoue avant toute exécution), puis les dépôts s'exécutent **séquentiellement** (le parallélisme reste borné *au sein* d'un dépôt) sous un en-tête `══ <repo>`, avec un récapitulatif / rapport taggé `<repo>/<worktree>` et un code de sortie agrégé. `--profile` se résout par dépôt contre son propre `.gwm.toml` ; un slug ne correspondant à rien dans un dépôt n'y contribue rien. `gwm clean --workspace` agrège un seul rapport et une seule décision `--yes` sur tous les dépôts ; un échec de suppression dans un worktree est rapporté mais n'interrompt pas les autres. **`--workspace` reste refusé sur les commandes qui ne l'implémentent pas.**
- **`gwm` seul** dans un répertoire qui n'est *pas* lui-même un dépôt git mais contient des dépôts enfants invite `No git repo here. Open <dir> as a workspace? [Y/n]`. L'invite est **déclinée silencieusement quand stdin n'est pas un terminal**, donc les pipes / la CI conservent l'ancien comportement mono-dépôt.
- **`.gwm.toml` reste par dépôt** — chaque ligne hérite de la config de son propre dépôt. Il n'y a pas de config au niveau workspace dans cette version ; le keymap et le thème sont résolus une fois depuis le premier dépôt, conformément au contrat mono-dépôt « résolu une fois, relancer pour changer ».
## `gwm trust {list|revoke|show}` (issue #95)
Gère le registre de confiance TOFU qui conditionne le bootstrap de `.gwm.toml` sur `gwm create` / `gwm bootstrap`. Le registre vit à `~/.config/gwm/trust.toml` par défaut ; à surcharger avec `$GWM_TRUST_LEDGER`.
- `gwm trust list` — affiche chaque tuple enregistré `(origin, sha-prefix, trusted_at, trusted_by)`. Un registre vide affiche `0 entries in trust ledger (<path>)` et sort 0.
- `gwm trust revoke <origin>` — supprime chaque entrée correspondant à `<origin>` à l'identique (les variantes SSH et HTTPS du même dépôt GitHub sont des chemins de confiance distincts). Rapporte `0 entries matched` quand rien ne change.
- `gwm trust show` — affiche le chemin du registre actif et son corps TOML brut (ou un avis « file does not exist yet » sur les installations fraîches). Utile pour trier les « pourquoi gwm me redemande-t-il ? » — comparez à l'œil le hash enregistré avec `sha256sum .gwm.toml`.
Deux flags **globaux** interagissent avec le registre sur chaque sous-commande qui lance le bootstrap (`gwm create`, `gwm bootstrap`) :
- `--allow-bootstrap` (aussi `GWM_ALLOW_BOOTSTRAP=1`) saute l'invite de confiance sans enregistrer. À utiliser dans les runners CI et autres contextes non interactifs.
- `--deny-bootstrap` refuse de lancer le bootstrap même si le registre dit « trusted ». Mode forensique pour une première inspection d'un dépôt inconnu.
Modèle de menace et justification complète : voir le commentaire au niveau module dans [`src/trust.rs`](https://github.com/kbrdn1/gwm-cli/blob/main/src/trust.rs).
## `gwm aliases list` (issue #86)
Affiche la chaîne d'alias CLI résolue — chaque alias atteignable depuis `gwm <name>`, groupé par source. En lecture seule ; l'édition déclarative se fait directement dans `.gwm.toml` (niveau dépôt) et `~/.config/gwm/aliases.toml` (niveau utilisateur).
```bash
gwm aliases list
```
Exemple de sortie :
```text
built-in:
cd → path
s → switch
repo (.gwm.toml):
ll → list --format names
wip → create feat 0 wip
user (~/.config/gwm/aliases.toml):
copy → path (shadowed by repo)
```
Ordre de résolution (précédence la plus haute en premier) :
1. **Sous-commandes intégrées** (`gwm list`, `gwm switch`, …) — jamais masquables.
2. **Alias visibles intégrés** (`s → switch`, `cd → path`) — également jamais masquables.
3. **Dépôt (`.gwm.toml` `[aliases]`)** — suit le dépôt à travers les machines.
4. **Utilisateur (`~/.config/gwm/aliases.toml` `[aliases]`)** — survit aux réinstallations de machine ; invisible pour les coéquipiers.
Les alias sont **une simple substitution d'argv** — `wip = "create feat 0 wip"` fait que `gwm wip` se comporte comme `gwm create feat 0 wip`. L'expansion se produit AVANT que clap parse argv. Les pipelines de shell (`&&`, `||`, `|`, `;`, backticks) dans les valeurs sont refusés au chargement — utilisez plutôt un alias de shell.
Les noms qui masquent une sous-commande intégrée ou un alias visible sont une erreur de config dure remontée par `Config::load_for_repo` (par ex. vous ne pouvez pas définir `list = "..."`). Expansion en une seule passe — les alias chaînés ne récursent pas.
## `gwm theme {list|show <name>}` (issue #33)
Inspecte les presets de couleurs TUI intégrés qui sous-tendent le bloc `[theme]` dans `.gwm.toml`.
```bash
gwm theme list # print every built-in preset name
gwm theme show catppuccin # dump the preset as a [theme] block
gwm theme show claude-dark | tee -a .gwm.toml # paste a preset into config
```
- `gwm theme list` — affiche les noms de chaque preset intégré : `catppuccin`, `gruvbox`, `tokyo-night`, `claude-dark` (le dernier résout aussi sous l'alias `claude`).
- `gwm theme show <name>` — affiche le preset nommé en un bloc TOML `[theme]` copiable-collable et réversible que vous pouvez déposer dans `.gwm.toml` et ajuster par rôle.
Schéma, liste des rôles et overrides par rôle : [Configuration → `[theme]`](/fr/configuration/gwm-toml#theme). L'overlay d'aide conscient du keymap du TUI et les cadres modaux tirent leurs couleurs du thème résolu — voir la [page des raccourcis clavier du TUI](/fr/tui/keybindings).
## `gwm tui keys` (issue #87)
Affiche le keymap TUI résolu — les valeurs par défaut intégrées superposées aux overrides `[tui.keys]` de `.gwm.toml` — avec la source par ligne.
```bash
gwm tui keys
# → action keys source
# down j, Down default
# up Ctrl+n .gwm.toml
# top g g default
# …
```
La colonne action liste les slugs acceptés dans `[tui.keys]` ; la colonne keys montre chaque accord lié à cette action (séparés par des virgules). Une colonne keys vide signifie que l'action est actuellement non liée (l'utilisateur l'a explicitement effacée). Réservée comme sous-arbre (`gwm tui …`) pour que les futurs réglages TUI atterrissent sans encombrer la surface de premier niveau.
Référence du keymap et grammaire des accords : [TUI → Raccourcis clavier](/fr/tui/keybindings) ; le schéma `[tui.keys]` : [Configuration → `[tui.keys]`](/fr/configuration/gwm-toml#tuikeys).
## `gwm exec [<slug>...] [--profile <nom>] [--jobs <n>] -- <cmd>` (issues #313, #324)
Lance une commande dans chaque worktree — séquentiellement par défaut, ou avec un parallélisme borné — une corvée de flotte sur chaque worktree du dépôt.
```bash
gwm exec -- git fetch # run `git fetch` in every non-main worktree
gwm exec feat-1 fix-2 -- cargo check # scope to two fuzzy-matched worktrees
gwm exec -- git log --oneline -5 # everything after `--` is forwarded verbatim
gwm exec --profile test # run the saved [exec.profiles.test] command
gwm exec --jobs 4 -- cargo build # fan out 4 worktrees at a time
```
Les slugs positionnels **avant** `--` cadrent l'ensemble (correspondance fuzzy, le même matcher que `gwm path` / `remove`) ; sans aucun, il cible chaque worktree non principal. Tout ce qui est **après** `--` est la commande, transmise telle quelle — flags compris. gwm affiche un en-tête `━━ <name> (<path>)` par worktree, puis un récapitulatif `✓ / ✗` par worktree, et sort avec un code non nul si la commande d'un worktree a échoué (vous pouvez donc en faire un garde de CI). Un ensemble cible vide affiche `no worktrees to run in` et sort `0`.
`--profile <nom>` lance une commande sauvegardée [`[exec.profiles.<nom>]`](/fr/configuration/gwm-toml#exec-et-clean) au lieu d'un inline. Le `command` du profil est un **tableau** d'argv exécuté **sans shell** — le même contrat que la forme inline, et une divergence délibérée avec le `command` ligne-shell de `[git_tui]` / `[review]`. `--profile` et un inline `-- <cmd>` sont **mutuellement exclusifs** (les fournir ensemble sort en `1`) ; un nom de profil **inconnu** sort en `1`.
`--jobs <n>` définit un **parallélisme borné**. `1` (le défaut) s'exécute séquentiellement avec la sortie live héritée. `> 1` lance jusqu'à N worktrees à la fois, en capturant la sortie de chacun et en l'imprimant en un bloc par worktree (dans l'ordre des worktrees) une fois le fan-out terminé — pour que les exécutions concurrentes ne s'entremêlent pas. Précédence : `--jobs` > le [`jobs`](/fr/configuration/gwm-toml#exec-et-clean) d'un profil > `[exec] jobs` > `1`. Le code de sortie agrégé est inchangé.
Cela lance la propre commande de l'utilisateur contre ses propres worktrees, donc **aucun garde de confiance de bootstrap** ([`gwm trust`](#gwm-trust-listrevokeshow-issue-95)) ne s'applique. Ce n'est **pas** journalisé dans [`gwm history`](#gwm-history---limit-n---all).
## `gwm clean [<slug>...] [--profile <nom>] [--yes]` (issues #313, #324)
Rapporte — et optionnellement récupère — les artefacts de build lourds à travers les worktrees. **Rapport seul par défaut.**
```bash
gwm clean # report reclaimable artifacts in every non-main worktree
gwm clean feat-1 # scope to a fuzzy-matched worktree
gwm clean --yes # actually delete the listed artifacts
gwm clean --profile deep # use the [clean.profiles.deep] directory set
```
`gwm clean` scanne chaque worktree cible pour `target/`, `node_modules/`, `dist/` et `build/` et affiche la taille récupérable par worktree. Les slugs positionnels cadrent l'ensemble (fuzzy) ; sans aucun, il cible chaque worktree non principal. Sans `--yes` il se contente de rapporter et affiche `re-run with --yes to delete the listed artifacts` ; un résultat vide affiche `nothing to reclaim`.
| Flag | Action |
|:-------------------|:---------------------------------------------------------------------|
| `--profile <nom>` | Récupère le jeu de répertoires [`[clean.profiles.<nom>]`](/fr/configuration/gwm-toml#exec-et-clean) — un jeu **complet** qui remplace les intégrés (un nom inconnu sort en `1`) |
| `--yes` | Supprime les artefacts listés au lieu de seulement les rapporter |
Sans `--profile`, `gwm clean` utilise `[clean.profiles.default]` quand ce profil est défini, sinon les `target`/`node_modules`/`dist`/`build` intégrés. Le `dirs` d'un profil **remplace** les intégrés (ne s'y ajoute jamais) ; la barrière de sûreté ci-dessous s'applique toujours à chaque répertoire.
**Sûreté :** `--yes` supprime un répertoire **uniquement** quand git le traite comme ignoré *et* qu'il ne contient aucun fichier suivi. Un `dist/` ou `build/` qui est suivi ou rédigé à la main (donc non régénérable) est rapporté comme `skipped … not git-ignored, or holds tracked files`, jamais supprimé. Parce que les artefacts sont régénérables, `gwm clean` est **délibérément non journalisé** dans [`gwm history`](#gwm-history---limit-n---all) — il n'y a pas de `gwm undo` pour lui.
## codes de sortie
| Code | Signification |
|:-----|:-----------------------------------------------------------------------|
| `0` | succès — aussi « tout au vert » pour `gwm doctor` |
| `1` | échec récupérable — échec fuzzy, correspondance ambiguë, Warning du doctor |
| `2` | échec dur — bootstrap `✗`, Failure du doctor, erreur git irrécupérable |