summaryrefslogtreecommitdiffstats
path: root/git_command.py
diff options
context:
space:
mode:
Diffstat (limited to 'git_command.py')
-rw-r--r--git_command.py74
1 files changed, 72 insertions, 2 deletions
diff --git a/git_command.py b/git_command.py
index c7245ade..588a64fd 100644
--- a/git_command.py
+++ b/git_command.py
@@ -40,6 +40,10 @@ GIT_DIR = "GIT_DIR"
40 40
41LAST_GITDIR = None 41LAST_GITDIR = None
42LAST_CWD = None 42LAST_CWD = None
43DEFAULT_GIT_FAIL_MESSAGE = "git command failure"
44# Common line length limit
45GIT_ERROR_STDOUT_LINES = 1
46GIT_ERROR_STDERR_LINES = 1
43 47
44 48
45class _GitCall(object): 49class _GitCall(object):
@@ -237,6 +241,7 @@ class GitCommand(object):
237 cwd=None, 241 cwd=None,
238 gitdir=None, 242 gitdir=None,
239 objdir=None, 243 objdir=None,
244 verify_command=False,
240 ): 245 ):
241 if project: 246 if project:
242 if not cwd: 247 if not cwd:
@@ -244,6 +249,10 @@ class GitCommand(object):
244 if not gitdir: 249 if not gitdir:
245 gitdir = project.gitdir 250 gitdir = project.gitdir
246 251
252 self.project = project
253 self.cmdv = cmdv
254 self.verify_command = verify_command
255
247 # Git on Windows wants its paths only using / for reliability. 256 # Git on Windows wants its paths only using / for reliability.
248 if platform_utils.isWindows(): 257 if platform_utils.isWindows():
249 if objdir: 258 if objdir:
@@ -332,7 +341,11 @@ class GitCommand(object):
332 stderr=stderr, 341 stderr=stderr,
333 ) 342 )
334 except Exception as e: 343 except Exception as e:
335 raise GitError("%s: %s" % (command[1], e)) 344 raise GitCommandError(
345 message="%s: %s" % (command[1], e),
346 project=project.name if project else None,
347 command_args=cmdv,
348 )
336 349
337 if ssh_proxy: 350 if ssh_proxy:
338 ssh_proxy.add_client(p) 351 ssh_proxy.add_client(p)
@@ -366,4 +379,61 @@ class GitCommand(object):
366 return env 379 return env
367 380
368 def Wait(self): 381 def Wait(self):
369 return self.rc 382 if not self.verify_command or self.rc == 0:
383 return self.rc
384
385 stdout = (
386 "\n".join(self.stdout.split("\n")[:GIT_ERROR_STDOUT_LINES])
387 if self.stdout
388 else None
389 )
390
391 stderr = (
392 "\n".join(self.stderr.split("\n")[:GIT_ERROR_STDERR_LINES])
393 if self.stderr
394 else None
395 )
396 project = self.project.name if self.project else None
397 raise GitCommandError(
398 project=project,
399 command_args=self.cmdv,
400 git_rc=self.rc,
401 git_stdout=stdout,
402 git_stderr=stderr,
403 )
404
405
406class GitCommandError(GitError):
407 """
408 Error raised from a failed git command.
409 Note that GitError can refer to any Git related error (e.g. branch not
410 specified for project.py 'UploadForReview'), while GitCommandError is
411 raised exclusively from non-zero exit codes returned from git commands.
412 """
413
414 def __init__(
415 self,
416 message: str = DEFAULT_GIT_FAIL_MESSAGE,
417 git_rc: int = None,
418 git_stdout: str = None,
419 git_stderr: str = None,
420 **kwargs,
421 ):
422 super().__init__(
423 message,
424 **kwargs,
425 )
426 self.git_rc = git_rc
427 self.git_stdout = git_stdout
428 self.git_stderr = git_stderr
429
430 def __str__(self):
431 args = "[]" if not self.command_args else " ".join(self.command_args)
432 error_type = type(self).__name__
433 return f"""{error_type}: {self.message}
434 Project: {self.project}
435 Args: {args}
436 Stdout:
437{self.git_stdout}
438 Stderr:
439{self.git_stderr}"""