fix git command taking too long and crashing

This commit is contained in:
Martin Sekera 2021-02-28 00:32:53 +01:00
parent 5bff961095
commit eedbc09193

View file

@ -7,6 +7,7 @@ import pwd
import socket
import subprocess
import sys
import time
COLOR_LOAD_IDLE = 10
COLOR_LOAD_OK = 2
@ -321,14 +322,19 @@ class PathPart(Part):
def command(cmd, timeout=0.5):
"""
Executes a command, returns stdout, suppresses stderr."
Executes a command, returns stdout, suppresses stderr.
Kills the process on timeout.
"""
if type(cmd) == str:
cmd = cmd.split()
s = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
s.wait(timeout)
try:
s = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
s.wait(timeout)
except subprocess.TimeoutExpired:
s.kill()
raise
return s.stdout.read().decode("utf-8")
@ -410,6 +416,15 @@ class WineprefixPart(Part):
else:
self.fragments.append(":64")
class TimeBudget:
def __init__(self, budget, min=0.1):
self.end = time.monotonic() + budget
self.min = min
@property
def trem(self):
return max(self.min, self.end - time.monotonic())
class GitPart(Part):
"""
2 4 M master ?11 6 10
@ -427,20 +442,21 @@ class GitPart(Part):
def __init__(self):
Part.__init__(self)
tb = TimeBudget(1) # don't spend more than a second here
branch_name = command("git name-rev --name-only --no-undefined --always HEAD").strip()
try:
branch_name = command("git name-rev --name-only --no-undefined --always HEAD", tb.trem).strip()
if branch_name:
try:
if branch_name:
self.fragments.append("")
count_to_pull = command("git log --oneline ..@{u}").count("\n")
count_to_push = command("git log --oneline @{u}..").count("\n")
git_dir = command("git rev-parse --git-dir").strip()
count_to_pull = command("git log --oneline ..@{u}", tb.trem).count("\n")
count_to_push = command("git log --oneline @{u}..", tb.trem).count("\n")
git_dir = command("git rev-parse --git-dir", tb.trem).strip()
merging = os.path.exists(os.path.join(git_dir, "MERGE_HEAD"))
untracked = command("git ls-files --other --exclude-standard", timeout=0.2).count("\n")
modified = command("git diff --name-only").count("\n")
staged = command("git diff --name-only --staged").count("\n")
untracked = command("git ls-files --other --exclude-standard", tb.trem).count("\n")
modified = command("git diff --name-only", tb.trem).count("\n")
staged = command("git diff --name-only --staged", tb.trem).count("\n")
if count_to_pull:
self.fragments.append("%d " %(count_to_pull))
@ -473,11 +489,12 @@ class GitPart(Part):
self.fragments.append("%d" %(staged))
self.fragments.append(style_reset())
except subprocess.TimeoutExpired:
self.fragments = []
self.fragments.append(style_color(COLOR_GIT_DIRTY))
self.fragments.append("⚠ git timeout ⚠")
self.fragments.append(style_reset())
except subprocess.TimeoutExpired:
self.fragments = []
self.fragments.append(style_color(COLOR_GIT_DIRTY))
self.fragments.append("⚠ git timeout ⚠")
self.fragments.append(style_reset())
class Padding(Part):
def __init__(self, term_width):