38 votes

Git Bash reste bloqué sur diff / log, répète spontanément la même commande encore et encore

Je rencontre un problème étrange avec Git Bash sur Windows 7 / XP. Ça marchait bien avant, mais récemment, je trouve qu'après avoir effectué un git diff ou un git log, Git Bash devient inutilisable : après le diff/log, même après être retourné à l'invite de commande, Bash continue soudainement et apparemment de manière spontanée à répéter la même commande, sans être sollicité, alors que je suis en train de taper une commande suivante.

Est-ce que quelqu'un d'autre a eu ce problème ? Tout conseil serait grandement apprécié, car cela limite vraiment l'utilité de Git Bash pour le moment.

0 votes

Sortez-vous du pager avec q ?

0 votes

Ah, non - j'utilisais Ctrl-C pour revenir à l'invite de commande. Est-ce que c'est incorrect? La chose étrange est que ça marchait bien avant, mais maintenant ça ne marche plus.

0 votes

Ctrl-C ne devrait pas quitter le pager (et ce n'est pas le cas sur un système Linux). Lorsque vous appuyez sur Ctrl-C sur Windows (msysgit je suppose?), vous tuez d'une certaine manière le processus "de l'extérieur" (c'est-à-dire à partir de cmd.exe).

56voto

knittl Points 64110

Vous devez utiliser q pour quitter le pager de git. Utiliser Ctrl-C ne fait que causer des problèmes sur Windows.

Ctrl-C ne devrait pas quitter le pager (et ce n'est pas le cas sur un système Linux). Lorsque vous appuyez sur Ctrl-C sur Windows (msysgit je suppose?), vous arrêtez d'une manière ou d'une autre le processus "de l'extérieur" (c'est-à-dire de cmd.exe). Je ne connais pas les raisons exactes de cela.

Comme j'ai déjà rencontré des problèmes similaires par le passé : essayez d'appuyer à plusieurs reprises sur q et Ctrl-C dans un ordre aléatoire, si vous avez de la chance, vous retrouverez un invite de commande fonctionnel ;) [Il n'y a pas de meilleure solution que je connaisse - mais cela a fonctionné pour moi ...]

0 votes

Merci, cela règle totalement le problème! J'utilise en effet msysgit. C'est légèrement gênant que j'appuyais juste sur la mauvaise touche... C'est étrange et déroutant cependant que Ctrl-C fonctionne presque. Quoi qu'il en soit, merci encore.

0 votes

Une fois que j'ai arrêté d'utiliser Ctrl+C - plus de bugs! Merci

0 votes

Sur Ubuntu 11, j'ai résolu cela en fermant et en rouvrant le terminal.

2voto

VonC Points 414372

Notez qu'avec Git 2.12 (Q1 2017, 6+ ans plus tard), un fichier Ctrl + C dans une session git pager devrait mieux se comporter.

Véase commit 46df690 , commit 246f0ed , commit 2b296c9 (07 janv. 2017) par Jeff King ( peff ) .
(fusionné par Junio C Hamano -- gitster -- en commit 5918bdc , 18 janv. 2017)

execv_dashed_external : attendre l'enfant au signal de la mort

Dactylographie ^C a pager qui ne le tue généralement pas, a tué Git et a fait tomber le pager en tant que dommage collatéral dans la structure de l'arbre de certains processus.
Ce point a été corrigé.

Vous pouvez exécuter n'importe quelle commande externe en pointillés avec des commandes telles que git -p stash list où la commande s'achève, mais où le récepteur de radiomessagerie continue à fonctionner.

La version courte est que tout devrait s'arrêter normalement (Git et pager).

Mais en détail :

Quand git dirige un pager il est important pour le processus git de attende que le processus pager pour finir, même si elle n'a plus de données à lui fournir.
Cela s'explique par le fait que git fait naître le pager en tant qu'enfant, et donc le git est le chef de session sur le terminal. Après sa mort, le processus pager terminera sa lecture en cours du terminal (en mangeant celui qui est en cours). ), puis obtiendra EIO essayer de lire à nouveau.

Nota: EIO (error 5) signifie Error I/O, et est ( source ) le :

Le système est un fourre-tout pour toutes sortes d'erreurs matérielles inattendues. Il peut s'agir d'une erreur physique, mais en outre, un processus orphelin (un processus dont le parent est mort) qui tente de lire à partir de l'entrée standard obtiendra ce message. Les systèmes BSD renvoient ce message si vous essayez d'ouvrir un périphérique pty qui est déjà utilisé.
Une tentative de lecture à partir d'un flux fermé renverra un message EIO, de même qu'une lecture ou une écriture sur un disque en dehors des limites physiques du périphérique.
Une ouverture de /dev/tty lorsque le processus n'a pas de contrôle tty recrachera EIO également.

Ainsi (retour à ^C dans un pager ) :

Lorsque vous appuyez sur ^C qui envoie SIGINT a git et au pager , et la situation est similaire.
Les pager l'ignore, mais le git doit rester en place jusqu'à ce que le téléavertisseur ait terminé. Nous avons abordé cette question il y a longtemps dans a3da882 (pager : do wait_for_pager on signal death, 2009-01-22) .

Mais lorsque vous avez un external dashed (ou un alias pointant vers un builtin, qui ré-exécutera git pour le builtin), il y a un processus supplémentaire dans le mélange.
Par exemple, la course à pied :

$ git -c alias.l=log l

vous obtiendrez une arborescence de processus comme :

  git (parent)
    \
     git-log (child)
      \
       less (pager)

Si vous frappez ^C , SIGINT s'adresse à chacun d'entre eux. Le pager l'ignore, et le processus git enfant se retrouve dans wait_for_pager().
Mais le processus parent git mourra, et les problèmes habituels d'EIO se produiront.


Avec Git 2.28 (Q3 2020), lorsqu'une commande aliasée, dont la sortie est acheminée vers un pager par git, est tuée par un signal, le pager se retrouve dans un drôle d'état, ce qui a été corrigé (à nouveau).

Véase commit c0d73a5 , commit e662df7 (07 Jul 2020) par Trygve Aaberge ( trygveaa ) .
(fusionné par Junio C Hamano -- gitster -- en commit 05920f0 , 15 juillet 2020)

Ctrl+C Attendre la mort de l'enfant sur le signal pour les alias à construire

Signé par : Trygve Aaberge

Lorsque vous appuyez sur ^C, tous les processus de l'arbre le reçoivent.
Lorsqu'un git utilise un pager, git l'ignore et attend que le pager quitte.

Toutefois, lorsqu'un alias est utilisé, il existe un processus supplémentaire dans l'arbre qui n'a pas ignoré le signal. Cela l'a fait sortir, ce qui a entraîné la sortie du pager. Ceci corrige ce problème pour les alias vers les builtins.

Ce problème a été corrigé à l'origine dans 46df6906 ( execv_dashed_external : attendre l'enfant sur le signal de la mort, 2017-01-06), mais a été cassé par ee4512ed (" trace2 : create new combined trace facility", 2019-02-22, Git v2.22.0-rc0 -- fusionner figurant sur la liste des lot n°2 ) et ensuite b9140840 (" git : avoid calling aliased builtins via their dashed form", 2019-07-29, Git v2.23.0-rc1 -- fusionner ).

Et.. :

Lorsque nous lançons un alias vers une commande externe, nous voulons attendre que ce processus se termine même après avoir reçu ^C qui tue normalement le processus git. C'est utile lorsque le processus ignore le SIGINT (ce que font souvent les pagers par exemple), et que nous ne voulons pas qu'il soit tué.

Avoir un alias qui invoque un pager n'est probablement pas courant, mais cela peut être utile, par exemple si vous avez un alias vers une commande git qui utilise un subshell comme l'un des arguments (dans ce cas, vous devez utiliser une commande externe, et non un alias vers une commande intégrée).

Ce correctif est similaire au commit précédent, mais le commit précédent ne corrigeait que les alias vers les builtins, alors que ce commit fait la même chose pour les alias vers les commandes externes. En plus d'attendre après le nettoyage comme dans le commit précédent, ceci permet également de nettoyer l'enfant (ce qui était déjà activé pour les alias vers les builtins avant le commit précédent), parce que wait_after_clean s'appuie sur elle. Enfin, bien que le commit précédent ait corrigé une régression, je ne pense pas que cela ait jamais fonctionné correctement.


Notez que si vous utilisez trace2 pour déboguer la situation, le téléavertisseur est maintenant correctement tracé.

Lorsqu'un pager créé par l'utilisateur se terminait, le journal de trace n'enregistrait pas correctement son état de sortie, ce qui a été corrigé avec Git 2.31 (Q1 2021).

Véase commit be8fc53 , commit 85db79a , commit c24b7f6 , commit 61ff12f (02 février 2021) par Ævar Arnfjörð Bjarmason ( avar ) .
(fusionné par Junio C Hamano -- gitster -- en engager dcb11fc , 22 février 2021)

pager : enregistrer correctement le code de sortie du téléavertisseur lorsqu'il est signalé

Signé par : Ævar Arnfjörð Bjarmason

Lorsque git invoque un pager qui sort avec une valeur non nulle, le cas le plus fréquent est que le pager renvoie déjà la bonne valeur de SIGPIPE mais le code de sortie enregistré dans la trace2 a toujours été signalé de manière incorrecte. 1 .
Corrigez cela et enregistrez le bon code de sortie dans les journaux.

Puisque cela nous donne quelque chose à tester en dehors de nos tests récemment ajoutés qui ont besoin d'un !MINGW nous allons remanier le test pour qu'il s'exécute sur le serveur MINGW et vérifie effectivement la présence de SIGPIPE en dehors de MINGW .

Les wait_or_whine() n'est appelé qu'avec un vrai "in_signal" à partir de à partir de finish_command_in_signal() qui, à son tour, n'est utilisé qu'en pager.c .

Le " in_signal && !WIFEXITED(status) "n'est pas couvert par les tests.
Pour faire bonne mesure, enregistrons la valeur par défaut -1 dans ce cas.

  1. L'enregistrement incorrect du code de sortie dans a été apparemment copié/collé dans finish_command_in_signal() en ee4512e (" trace2 : create new combined trace facility", 2019-02-22, Git v2.22.0-rc0 -- fusionner figurant sur la liste des lot n°2 )

0voto

Francesco Rogo Points 167

Une fois que vous êtes bloqué, essayez Ctrl-Break plutôt que Ctrl-c, cela fonctionne pour moi. (la touche Pause/Break réelle près de la touche Scroll Lock).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X