+def _gitenv(repo_dir=None):
+ if not repo_dir:
+ repo_dir = repo()
+ return merge_dict(environ, {b'GIT_DIR': os.path.abspath(repo_dir)})
+
+def _git_wait(cmd, p):
+ rv = p.wait()
+ if rv != 0:
+ raise GitError('%r returned %d' % (cmd, rv))
+
+def _git_exo(cmd, **kwargs):
+ kwargs['check'] = False
+ result = exo(cmd, **kwargs)
+ _, _, proc = result
+ if proc.returncode != 0:
+ raise GitError('%r returned %d' % (cmd, proc.returncode))
+ return result
+
+def git_config_get(option, repo_dir=None, opttype=None, cfg_file=None):
+ assert not (repo_dir and cfg_file), "repo_dir and cfg_file cannot both be used"
+ cmd = [b'git', b'config', b'--null']
+ if cfg_file:
+ cmd.extend([b'--file', cfg_file])
+ if opttype == 'int':
+ cmd.extend([b'--int'])
+ elif opttype == 'bool':
+ cmd.extend([b'--bool'])
+ else:
+ assert opttype is None
+ cmd.extend([b'--get', option])
+ env=None
+ if repo_dir:
+ env = _gitenv(repo_dir=repo_dir)
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env,
+ close_fds=True)
+ # with --null, git writes out a trailing \0 after the value
+ r = p.stdout.read()[:-1]
+ rc = p.wait()
+ if rc == 0:
+ if opttype == 'int':
+ return int(r)
+ elif opttype == 'bool':
+ # git converts to 'true' or 'false'
+ return r == b'true'
+ return r
+ if rc != 1:
+ raise GitError('%r returned %d' % (cmd, rc))
+ return None
+
+