-
Notifications
You must be signed in to change notification settings - Fork 547
Expand file tree
/
Copy pathgit.py
More file actions
57 lines (43 loc) · 1.65 KB
/
git.py
File metadata and controls
57 lines (43 loc) · 1.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import os.path
import subprocess
from typing import Set
from ..core.log import log
def get_root_directory(path: str = '') -> str:
"""
:raises: CalledProcessError
"""
command = ['git']
if path:
command.extend(['-C', path])
command.extend(['rev-parse', '--show-toplevel'])
return subprocess.check_output(command).decode('utf-8').strip()
def get_tracked_files(root: str) -> Set[str]:
"""Parsing .gitignore rules is hard.
However, a way we can get around this problem by just listing all
currently tracked git files, and start our search from there.
After all, if it isn't in the git repo, we're not concerned about
it, because secrets aren't being entered in a shared place.
:raises: CalledProcessError
"""
output = set()
try:
files = subprocess.check_output(
['git', '-C', root, 'ls-files'],
stderr=subprocess.DEVNULL,
)
for filename in files.decode('utf-8').splitlines():
path = os.path.relpath(os.path.join(root, filename), root)
if path:
output.add(path)
except subprocess.CalledProcessError:
pass
except FileNotFoundError: # pragma: no cover
log.warning('Unable to find `git` in PATH, and therefore, unable to get tracked files.')
return output
def get_changed_but_unstaged_files() -> Set[str]:
try:
files = subprocess.check_output('git diff --name-only'.split()).decode().splitlines()
except subprocess.CalledProcessError: # pragma: no cover
# Since we don't pipe stderr, we get free logging through git.
raise ValueError
return set(files)