5
5
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
6
6
7
7
import os , sys
8
- import subprocess
9
8
from utils import *
10
9
from errors import GitCommandError
11
10
11
+ from subprocess import (
12
+ call ,
13
+ Popen ,
14
+ PIPE
15
+ )
16
+
12
17
# Enables debugging of GitPython's git commands
13
18
GIT_PYTHON_TRACE = os .environ .get ("GIT_PYTHON_TRACE" , False )
14
19
15
20
execute_kwargs = ('istream' , 'with_keep_cwd' , 'with_extended_output' ,
16
21
'with_exceptions' , 'as_process' ,
17
22
'output_stream' )
18
23
19
-
24
+ __all__ = ( 'Git' , )
20
25
21
26
def dashify (string ):
22
27
return string .replace ('_' , '-' )
@@ -43,14 +48,12 @@ class Git(object):
43
48
max_chunk_size = 1024 * 64
44
49
45
50
class AutoInterrupt (object ):
46
- """
47
- Kill/Interrupt the stored process instance once this instance goes out of scope. It is
51
+ """Kill/Interrupt the stored process instance once this instance goes out of scope. It is
48
52
used to prevent processes piling up in case iterators stop reading.
49
53
Besides all attributes are wired through to the contained process object.
50
54
51
55
The wait method was overridden to perform automatic status code checking
52
- and possibly raise.
53
- """
56
+ and possibly raise."""
54
57
__slots__ = ("proc" , "args" )
55
58
56
59
def __init__ (self , proc , args ):
@@ -74,19 +77,16 @@ def __del__(self):
74
77
# for some reason, providing None for stdout/stderr still prints something. This is why
75
78
# we simply use the shell and redirect to nul. Its slower than CreateProcess, question
76
79
# is whether we really want to see all these messages. Its annoying no matter what.
77
- subprocess . call (("TASKKILL /F /T /PID %s 2>nul 1>nul" % str (self .proc .pid )), shell = True )
80
+ call (("TASKKILL /F /T /PID %s 2>nul 1>nul" % str (self .proc .pid )), shell = True )
78
81
# END exception handling
79
82
80
83
def __getattr__ (self , attr ):
81
84
return getattr (self .proc , attr )
82
85
83
86
def wait (self ):
84
- """
85
- Wait for the process and return its status code.
87
+ """Wait for the process and return its status code.
86
88
87
- Raise
88
- GitCommandError if the return status is not 0
89
- """
89
+ :raise GitCommandError: if the return status is not 0"""
90
90
status = self .proc .wait ()
91
91
if status != 0 :
92
92
raise GitCommandError (self .args , status , self .proc .stderr .read ())
@@ -196,15 +196,13 @@ def __del__(self):
196
196
197
197
198
198
def __init__ (self , working_dir = None ):
199
- """
200
- Initialize this instance with:
199
+ """Initialize this instance with:
201
200
202
- `` working_dir``
201
+ :param working_dir:
203
202
Git directory we should work in. If None, we always work in the current
204
203
directory as returned by os.getcwd().
205
204
It is meant to be the working tree directory if available, or the
206
- .git directory in case of bare repositories.
207
- """
205
+ .git directory in case of bare repositories."""
208
206
super (Git , self ).__init__ ()
209
207
self ._working_dir = working_dir
210
208
@@ -213,22 +211,16 @@ def __init__(self, working_dir=None):
213
211
self .cat_file_all = None
214
212
215
213
def __getattr__ (self , name ):
216
- """
217
- A convenience method as it allows to call the command as if it was
214
+ """A convenience method as it allows to call the command as if it was
218
215
an object.
219
- Returns
220
- Callable object that will execute call _call_process with your arguments.
221
- """
216
+ :return: Callable object that will execute call _call_process with your arguments."""
222
217
if name [:1 ] == '_' :
223
218
raise AttributeError (name )
224
219
return lambda * args , ** kwargs : self ._call_process (name , * args , ** kwargs )
225
220
226
221
@property
227
222
def working_dir (self ):
228
- """
229
- Returns
230
- Git directory we are working on
231
- """
223
+ """:return: Git directory we are working on"""
232
224
return self ._working_dir
233
225
234
226
def execute (self , command ,
@@ -240,30 +232,29 @@ def execute(self, command,
240
232
output_stream = None ,
241
233
** subprocess_kwargs
242
234
):
243
- """
244
- Handles executing the command on the shell and consumes and returns
235
+ """Handles executing the command on the shell and consumes and returns
245
236
the returned information (stdout)
246
237
247
- `` command``
238
+ :param command:
248
239
The command argument list to execute.
249
240
It should be a string, or a sequence of program arguments. The
250
241
program to execute is the first item in the args sequence or string.
251
242
252
- `` istream``
243
+ :param istream:
253
244
Standard input filehandle passed to subprocess.Popen.
254
245
255
- `` with_keep_cwd``
246
+ :param with_keep_cwd:
256
247
Whether to use the current working directory from os.getcwd().
257
248
The cmd otherwise uses its own working_dir that it has been initialized
258
249
with if possible.
259
250
260
- `` with_extended_output``
251
+ :param with_extended_output:
261
252
Whether to return a (status, stdout, stderr) tuple.
262
253
263
- `` with_exceptions``
254
+ :param with_exceptions:
264
255
Whether to raise an exception when git returns a non-zero status.
265
256
266
- `` as_process``
257
+ :param as_process:
267
258
Whether to return the created process instance directly from which
268
259
streams can be read on demand. This will render with_extended_output and
269
260
with_exceptions ineffective - the caller will have
@@ -273,35 +264,32 @@ def execute(self, command,
273
264
use the command in iterators, you should pass the whole process instance
274
265
instead of a single stream.
275
266
276
- `` output_stream``
267
+ :param output_stream:
277
268
If set to a file-like object, data produced by the git command will be
278
269
output to the given stream directly.
279
270
This feature only has any effect if as_process is False. Processes will
280
271
always be created with a pipe due to issues with subprocess.
281
272
This merely is a workaround as data will be copied from the
282
273
output pipe to the given output stream directly.
283
274
284
- `` **subprocess_kwargs``
275
+ :param **subprocess_kwargs:
285
276
Keyword arguments to be passed to subprocess.Popen. Please note that
286
277
some of the valid kwargs are already set by this method, the ones you
287
278
specify may not be the same ones.
288
279
289
- Returns::
290
-
291
- str(output) # extended_output = False (Default)
292
- tuple(int(status), str(stdout), str(stderr)) # extended_output = True
293
-
294
- if ouput_stream is True, the stdout value will be your output stream:
295
- output_stream # extended_output = False
296
- tuple(int(status), output_stream, str(stderr))# extended_output = True
297
-
298
- Raise
299
- GitCommandError
280
+ :return:
281
+ * str(output) if extended_output = False (Default)
282
+ * tuple(int(status), str(stdout), str(stderr)) if extended_output = True
283
+
284
+ if ouput_stream is True, the stdout value will be your output stream:
285
+ * output_stream if extended_output = False
286
+ * tuple(int(status), output_stream, str(stderr)) if extended_output = True
287
+
288
+ :raise GitCommandError:
300
289
301
- NOTE
290
+ :note:
302
291
If you add additional keyword arguments to the signature of this method,
303
- you must update the execute_kwargs tuple housed in this module.
304
- """
292
+ you must update the execute_kwargs tuple housed in this module."""
305
293
if GIT_PYTHON_TRACE and not GIT_PYTHON_TRACE == 'full' :
306
294
print ' ' .join (command )
307
295
@@ -312,14 +300,14 @@ def execute(self, command,
312
300
cwd = self ._working_dir
313
301
314
302
# Start the process
315
- proc = subprocess . Popen (command ,
316
- cwd = cwd ,
317
- stdin = istream ,
318
- stderr = subprocess . PIPE ,
319
- stdout = subprocess . PIPE ,
320
- close_fds = (os .name == 'posix' ),# unsupported on linux
321
- ** subprocess_kwargs
322
- )
303
+ proc = Popen (command ,
304
+ cwd = cwd ,
305
+ stdin = istream ,
306
+ stderr = PIPE ,
307
+ stdout = PIPE ,
308
+ close_fds = (os .name == 'posix' ),# unsupported on linux
309
+ ** subprocess_kwargs
310
+ )
323
311
if as_process :
324
312
return self .AutoInterrupt (proc , command )
325
313
@@ -367,10 +355,8 @@ def execute(self, command,
367
355
return stdout_value
368
356
369
357
def transform_kwargs (self , ** kwargs ):
370
- """
371
- Transforms Python style kwargs into git command line options.
372
- """
373
- args = []
358
+ """Transforms Python style kwargs into git command line options."""
359
+ args = list ()
374
360
for k , v in kwargs .items ():
375
361
if len (k ) == 1 :
376
362
if v is True :
@@ -400,34 +386,30 @@ def __unpack_args(cls, arg_list):
400
386
return outlist
401
387
402
388
def _call_process (self , method , * args , ** kwargs ):
403
- """
404
- Run the given git command with the specified arguments and return
389
+ """Run the given git command with the specified arguments and return
405
390
the result as a String
406
391
407
- `` method``
392
+ :param method:
408
393
is the command. Contained "_" characters will be converted to dashes,
409
394
such as in 'ls_files' to call 'ls-files'.
410
395
411
- `` args``
396
+ :param args:
412
397
is the list of arguments. If None is included, it will be pruned.
413
398
This allows your commands to call git more conveniently as None
414
399
is realized as non-existent
415
400
416
- `` kwargs``
401
+ :param kwargs:
417
402
is a dict of keyword arguments.
418
403
This function accepts the same optional keyword arguments
419
404
as execute().
420
405
421
- Examples::
406
+ `` Examples`` ::
422
407
git.rev_list('master', max_count=10, header=True)
423
408
424
- Returns
425
- Same as execute()
426
- """
427
-
409
+ :return: Same as ``execute``"""
428
410
# Handle optional arguments prior to calling transform_kwargs
429
411
# otherwise these'll end up in args, which is bad.
430
- _kwargs = {}
412
+ _kwargs = dict ()
431
413
for kwarg in execute_kwargs :
432
414
try :
433
415
_kwargs [kwarg ] = kwargs .pop (kwarg )
@@ -447,16 +429,13 @@ def _call_process(self, method, *args, **kwargs):
447
429
448
430
def _parse_object_header (self , header_line ):
449
431
"""
450
- `` header_line``
432
+ :param header_line:
451
433
<hex_sha> type_string size_as_int
452
434
453
- Returns
454
- (hex_sha, type_string, size_as_int)
435
+ :return: (hex_sha, type_string, size_as_int)
455
436
456
- Raises
457
- ValueError if the header contains indication for an error due to incorrect
458
- input sha
459
- """
437
+ :raise ValueError: if the header contains indication for an error due to
438
+ incorrect input sha"""
460
439
tokens = header_line .split ()
461
440
if len (tokens ) != 3 :
462
441
if not tokens :
@@ -482,7 +461,7 @@ def __get_persistent_cmd(self, attr_name, cmd_name, *args,**kwargs):
482
461
if cur_val is not None :
483
462
return cur_val
484
463
485
- options = { "istream" : subprocess . PIPE , "as_process" : True }
464
+ options = { "istream" : PIPE , "as_process" : True }
486
465
options .update ( kwargs )
487
466
488
467
cmd = self ._call_process ( cmd_name , * args , ** options )
@@ -501,15 +480,14 @@ def get_object_header(self, ref):
501
480
:note: The method will only suffer from the costs of command invocation
502
481
once and reuses the command in subsequent calls.
503
482
504
- :return: (hexsha, type_string, size_as_int) """
483
+ :return: (hexsha, type_string, size_as_int)"""
505
484
cmd = self .__get_persistent_cmd ("cat_file_header" , "cat_file" , batch_check = True )
506
485
return self .__get_object_header (cmd , ref )
507
486
508
487
def get_object_data (self , ref ):
509
488
""" As get_object_header, but returns object data as well
510
489
:return: (hexsha, type_string, size_as_int,data_string)
511
- :note: not threadsafe
512
- """
490
+ :note: not threadsafe"""
513
491
hexsha , typename , size , stream = self .stream_object_data (ref )
514
492
data = stream .read (size )
515
493
del (stream )
@@ -525,14 +503,11 @@ def stream_object_data(self, ref):
525
503
return (hexsha , typename , size , self .CatFileContentStream (size , cmd .stdout ))
526
504
527
505
def clear_cache (self ):
528
- """
529
- Clear all kinds of internal caches to release resources.
506
+ """Clear all kinds of internal caches to release resources.
530
507
531
508
Currently persistent commands will be interrupted.
532
509
533
- Returns
534
- self
535
- """
510
+ :return: self"""
536
511
self .cat_file_all = None
537
512
self .cat_file_header = None
538
513
return self
0 commit comments