4 from subprocess
import Popen
, PIPE
, check_call
7 # interpret a string as a whitespace-separated list of executable+arguments
8 if isinstance(args
, types
.StringTypes
):
10 t
= Popen(args
, stdout
=PIPE
)
11 stdout
= t
.communicate()[0]
13 raise OSError("Call %s failed" % args
)
16 class GitWrapper(object):
19 self
.supports_nofetch
= True
20 v
= run_command('git --version')
21 prefix
= 'git version '
23 sys
.stderr
.write('Cannot parse "git --version" output, '
24 'assuming new version')
25 if not v
.startswith(prefix
):
30 v
= [int(n
) for n
in v
.split('.')[:3]]
35 self
.supports_nofetch
= False
37 def submodule_clone(self
, name
):
39 # Use a depth greater than 1 for shallow clones to reduce the
40 # chance that required submodule versions are not fetched when
41 # all branch heads in the corresponding repo have moved ahead.
42 shallow_args
= ['--depth', '100']
45 if self
.supports_nofetch
:
46 nofetch_args
= ['--no-fetch']
49 if path
.exists(path
.join(name
, '.git')):
50 # If the submodule already exists just try to update it
51 check_call('git submodule sync'.split()+[name
])
52 check_call('git submodule update'.split()+[name
])
54 # Do things manually instead of using "git submodule update --init",
55 # because git's sucky submodule support has no way of giving
56 # options to the "git clone" command that would be needed for
58 repo_addr
= run_command('git config --get submodule.%s.url' % name
)
59 # old git versions fail to clone over an empty directory
63 # Don't fail if it already doesn't exist - having other
64 # failure cases continue and fail later is OK.
66 check_call('git clone'.split() + shallow_args
+ [repo_addr
, name
])
67 check_call('git submodule update'.split() + nofetch_args
+ [name
])
70 output
= run_command('git config --null --list')
72 for line
in output
.split(chr(0)):
75 name
, value
= line
.split('\n', 1)
79 def get_submodules(self
):
80 output
= run_command('git ls-files --stage')
82 for line
in output
.splitlines():
83 mode
, sha
, stage
, path
= line
.split(None, 3)
89 def foreach_submodule(self
, func
, recurse
=True):
90 for module
in self
.get_submodules():
91 if path
.exists(path
.join(module
, '.git')):
95 self
.foreach_submodule(func
)
98 def foreach_module(self
, func
):
100 self
.foreach_submodule(func
)
103 def parse_configfile(filename
):
104 if not path
.exists(filename
):
110 if not line
or line
.startswith('#'):