Push discards pre-push hook output, so an interactive hook looks like a hang
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Accessibilité débutants
- 76/100
Piste de recherche
Lisez internal/git/gitops.go autour de defaultOps.Push et internal/git/git.go autour de runInteractive, puis comparez le chemin de commit interactif existant. Reproduisez le scénario du hook pre-push et exécutez les tests d’intégration ; le travail est terminé lorsque les invites du hook, la sortie et la progression de git parviennent au terminal, tandis que les pushes rejetés renvoient toujours une erreur sans dupliquer stderr.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Summary
Every command that pushes (sync, push, submit, link) runs git push with stdout sent to /dev/null and stderr sent to an in-memory buffer that is only surfaced if the push fails. A pre-push hook that prompts for input therefore prints its question into the void while blocking on /dev/tty, and gh stack sync appears to hang forever with no output and no timeout.
The same discarding affects non-interactive hooks: their logging and git's own transfer progress never appear, so a merely slow hook (a test suite, a linter) is indistinguishable from a hang.
Steps to reproduce
- In a repo with a stack, add
.git/hooks/pre-push:
#!/bin/sh
echo "Run the full test suite? [y/N] "
read ans < /dev/tty
- Run
gh stack sync.
Expected: the hook's prompt appears and you can answer it.
Actual: output stops after Pushing N branches to origin... and the command waits indefinitely. Typing y + Enter unblocks it, but nothing on screen indicates input is wanted.
Root cause
internal/git/gitops.go → defaultOps.Push ends in runSilent, which routes through the package-level client in internal/git/git.go:16:
var client = &cligit.Client{}
The client is zero-valued, so Stdin, Stdout, and Stderr are nil, and Client.Command copies them straight onto the exec.Cmd (cli/cli/v2/git/client.go:95-97). Nil Stdout on an exec.Cmd means /dev/null; Command.Run swaps nil Stderr for a bytes.Buffer (cli/cli/v2/git/command.go:20-23) that is only read back on failure. The hook process still inherits the controlling terminal, so read < /dev/tty blocks on real keystrokes — but the prompt it wrote to stdout/stderr is gone. context.Background() with no timeout means the wait is unbounded.
Verified with a pre-push hook that wrote to stdout, stderr, and a log file: the log confirmed the hook ran, and neither stream reached the terminal.
The codebase already has the right helper for this — runInteractive (internal/git/git.go:60) wires os.Stdin/Stdout/Stderr and is used for git commit. Push never got equivalent treatment.
Suggested fix
Have Push run through runInteractive so hook prompts, hook output, and git's transfer progress reach the terminal as they are produced. Since git and the hook have then already written their own messages to stderr, the returned error should carry only the exit status rather than folding the buffered stderr back in and printing it twice.
I have this working locally with integration tests covering a real pre-push hook (output visible on success; stderr visible and an error returned when the hook rejects the push). Happy to open a PR if that's welcome, or leave it here for a maintainer to pick up.
Related
- #135 and #293 both ask for
--no-verify. This is a separate problem: those are about skipping hooks, this is about hooks that run correctly but invisibly. A--no-verifyflag would not fix the invisible-prompt hang for people who need their hooks to run.
- Langage dominant
- Go
- Étoiles
- 1.5k
- Forks
- 73
- Merge moyen
- 1 j 8 h
- PR mergées (30 j)
- 7
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de github/gh-stack
-
Difficulté 2/5 1-3 heures Accessibilité débutants 85/100
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 92/100
-
feature request topic: cli - general
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
-
feature request topic: auto-merge
Difficulté 2/5 1-3 heures Accessibilité débutants 68/100
-
bug topic: docs
Difficulté 1/5 Moins d'une heure Accessibilité débutants 68/100
Toutes les issues de github/gh-stack
Issues similaires
-
textual definition
Difficulté 1/5 Moins d'une heure Accessibilité débutants 90/100
geneontology/go-ontology#32653 ·
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 75/100
-
needs design
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
-
Priority/High ready-for-agent Severity/Major Type/Bug
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100