1
- """Utilities for verifying git integrity ."""
1
+ """Git utilities ."""
2
2
3
3
# Used also from setup.py, so don't pull in anything additional here (like mypy or typing):
4
4
import os
5
- import pipes
6
5
import subprocess
7
- import sys
8
-
9
- MYPY = False
10
- if MYPY :
11
- from typing import Iterator
12
6
13
7
14
8
def is_git_repo (dir : str ) -> bool :
@@ -27,36 +21,11 @@ def have_git() -> bool:
27
21
return False
28
22
29
23
30
- def get_submodules (dir : str ) -> "Iterator[str]" :
31
- """Return a list of all git top-level submodules in a given directory."""
32
- # It would be nicer to do
33
- # "git submodule foreach 'echo MODULE $name $path $sha1 $toplevel'"
34
- # but that wouldn't work on Windows.
35
- output = subprocess .check_output (["git" , "submodule" , "status" ], cwd = dir )
36
- # "<status><sha1> name desc"
37
- # status='-': not initialized
38
- # status='+': changed
39
- # status='u': merge conflicts
40
- # status=' ': up-to-date
41
- for line in output .splitlines ():
42
- # Skip the status indicator, as it could be a space can confuse the split.
43
- line = line [1 :]
44
- name = line .split (b" " )[1 ]
45
- yield name .decode (sys .getfilesystemencoding ())
46
-
47
-
48
24
def git_revision (dir : str ) -> bytes :
49
25
"""Get the SHA-1 of the HEAD of a git repository."""
50
26
return subprocess .check_output (["git" , "rev-parse" , "HEAD" ], cwd = dir ).strip ()
51
27
52
28
53
- def submodule_revision (dir : str , submodule : str ) -> bytes :
54
- """Get the SHA-1 a submodule is supposed to have."""
55
- output = subprocess .check_output (["git" , "ls-files" , "-s" , submodule ], cwd = dir ).strip ()
56
- # E.g.: "160000 e4a7edb949e0b920b16f61aeeb19fc3d328f3012 0 typeshed"
57
- return output .split ()[1 ]
58
-
59
-
60
29
def is_dirty (dir : str ) -> bool :
61
30
"""Check whether a git repository has uncommitted changes."""
62
31
output = subprocess .check_output (["git" , "status" , "-uno" , "--porcelain" ], cwd = dir )
@@ -67,74 +36,3 @@ def has_extra_files(dir: str) -> bool:
67
36
"""Check whether a git repository has untracked files."""
68
37
output = subprocess .check_output (["git" , "clean" , "--dry-run" , "-d" ], cwd = dir )
69
38
return output .strip () != b""
70
-
71
-
72
- def warn_no_git_executable () -> None :
73
- print ("Warning: Couldn't check git integrity. "
74
- "git executable not in path." , file = sys .stderr )
75
-
76
-
77
- def warn_dirty (dir : str ) -> None :
78
- print ("Warning: git module '{}' has uncommitted changes." .format (dir ),
79
- file = sys .stderr )
80
- print ("Go to the directory" , file = sys .stderr )
81
- print (" {}" .format (dir ), file = sys .stderr )
82
- print ("and commit or reset your changes" , file = sys .stderr )
83
-
84
-
85
- def warn_extra_files (dir : str ) -> None :
86
- print ("Warning: git module '{}' has untracked files." .format (dir ),
87
- file = sys .stderr )
88
- print ("Go to the directory" , file = sys .stderr )
89
- print (" {}" .format (dir ), file = sys .stderr )
90
- print ("and add & commit your new files." , file = sys .stderr )
91
-
92
-
93
- def chdir_prefix (dir : str ) -> str :
94
- """Return the command to change to the target directory, plus '&&'."""
95
- if os .path .relpath (dir ) != "." :
96
- return "cd " + pipes .quote (dir ) + " && "
97
- else :
98
- return ""
99
-
100
-
101
- def error_submodule_not_initialized (name : str , dir : str ) -> None :
102
- print ("Submodule '{}' not initialized." .format (name ), file = sys .stderr )
103
- print ("Please run:" , file = sys .stderr )
104
- print (" {}git submodule update --init {}" .format (
105
- chdir_prefix (dir ), name ), file = sys .stderr )
106
-
107
-
108
- def error_submodule_not_updated (name : str , dir : str ) -> None :
109
- print ("Submodule '{}' not updated." .format (name ), file = sys .stderr )
110
- print ("Please run:" , file = sys .stderr )
111
- print (" {}git submodule update {}" .format (
112
- chdir_prefix (dir ), name ), file = sys .stderr )
113
- print ("(If you got this message because you updated {} yourself" .format (name ), file = sys .stderr )
114
- print (" then run \" git add {}\" to silence this check)" .format (name ), file = sys .stderr )
115
-
116
-
117
- def verify_git_integrity_or_abort (datadir : str ) -> None :
118
- """Verify the (submodule) integrity of a git repository.
119
-
120
- Potentially output warnings/errors (to stderr), and exit with status 1
121
- if we detected a severe problem.
122
- """
123
- datadir = datadir or '.'
124
- if not is_git_repo (datadir ):
125
- return
126
- if not have_git ():
127
- warn_no_git_executable ()
128
- return
129
- for submodule in get_submodules (datadir ):
130
- submodule_path = os .path .join (datadir , submodule )
131
- if not is_git_repo (submodule_path ):
132
- error_submodule_not_initialized (submodule , datadir )
133
- sys .exit (1 )
134
- elif submodule_revision (datadir , submodule ) != git_revision (submodule_path ):
135
- error_submodule_not_updated (submodule , datadir )
136
- sys .exit (1 )
137
- elif is_dirty (submodule_path ):
138
- warn_dirty (submodule )
139
- elif has_extra_files (submodule_path ):
140
- warn_extra_files (submodule )
0 commit comments