Skip to content

KeyboardInterrupt during git is not getting forwarded properly #1026

Closed

Description

@asottile

This causes (among other things) patches to not get re-applied

For instance:

$ git commit
[WARNING] Unstaged files detected.
[INFO] Stashing unstaged files to /home/asottile/.cache/pre-commit/patch1557511217.
python-modernize.........................................................Passed
pylint...................................................................^C
Traceback (most recent call last):
  File ".git/hooks/pre-commit", line 185, in <module>
    exit(main())
  File ".git/hooks/pre-commit", line 176, in main
    return retv | subprocess.call(_exe() + _opts(stdin))
  File "/usr/lib/python3.6/subprocess.py", line 269, in call
    return p.wait(timeout=timeout)
  File "/usr/lib/python3.6/subprocess.py", line 1457, in wait
    (pid, sts) = self._try_wait(0)
  File "/usr/lib/python3.6/subprocess.py", line 1404, in _try_wait
    (pid, sts) = os.waitpid(self.pid, wait_flags)
KeyboardInterrupt

This causes the patch file to not get restored!

Here's a potential solution:

--- .git/hooks/pre-commit	2019-05-10 10:57:23.555676222 -0700
+++ new	2019-05-10 10:57:21.467754348 -0700
@@ -169,11 +169,30 @@
     return ('--config', CONFIG, '--hook-stage', stage) + fns[HOOK_TYPE](stdin)
 
 
+def call2(cmd):
+    import signal
+
+    proc = None
+
+    def handler(*_):
+        if proc is None:
+            raise KeyboardInterrupt
+        else:
+            proc.send_signal(signal.SIGINT)
+
+    signal.signal(signal.SIGINT, handler)
+    try:
+        proc = subprocess.Popen(cmd)
+        return proc.wait()
+    finally:
+        signal.signal(signal.SIGINT, signal.SIG_DFL)
+
+
 def main():
     retv, stdin = _run_legacy()
     try:
         _validate_config()
-        return retv | subprocess.call(_exe() + _opts(stdin))
+        return retv | call2(_exe() + _opts(stdin))
     except EarlyExit:
         return retv
     except FatalError as e:

unclear if it works on windows, haven't had time to test yet (my guess is it doesn't because of signaling

At the same time, I should also improve the output during KeyboardInterrupt -- right now there's a large stacktrace -- can probably make that get caught by the error_handler

Activity

  1. asottile commented on May 10, 2019

    @asottile
    MemberAuthor

    interestingly this seems to only affect python3.x

  2. changed the title [-]KeyboardInterrupt during git is not getting forward properly[/-] [+]KeyboardInterrupt during git is not getting forwarded properly[/+] on May 11, 2019
  3. asottile commented on May 13, 2019

    @asottile
    MemberAuthor

    Thanks @chriskuehl for looking more into this, it appears to be related to these python bugs and should only affect python3.3 - python3.6:

    From some poking on stackoverflow this appears to be the "best" way to make this work:

    https://stackoverflow.com/a/47112580/812183

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions