@@ -72,6 +72,7 @@ class Repo(object):
72
72
_working_tree_dir = None
73
73
git_dir = None
74
74
_common_dir = None
75
+ isolated = False
75
76
76
77
# precompiled regex
77
78
re_whitespace = re .compile (r'\s+' )
@@ -89,7 +90,8 @@ class Repo(object):
89
90
# Subclasses may easily bring in their own custom types by placing a constructor or type here
90
91
GitCommandWrapperType = Git
91
92
92
- def __init__ (self , path = None , odbt = GitCmdObjectDB , search_parent_directories = False , expand_vars = True ):
93
+ def __init__ (self , path = None , odbt = GitCmdObjectDB , search_parent_directories = False , expand_vars = True ,
94
+ isolated = False ):
93
95
"""Create a new Repo instance
94
96
95
97
:param path:
@@ -113,11 +115,21 @@ def __init__(self, path=None, odbt=GitCmdObjectDB, search_parent_directories=Fal
113
115
114
116
Please note that this was the default behaviour in older versions of GitPython,
115
117
which is considered a bug though.
118
+ :param isolated:
119
+ If True, the current environment variables will be isolated from git as much as possible.
120
+ Specifically the GIT_* variables are ignored as much as possible.
121
+
116
122
:raise InvalidGitRepositoryError:
117
123
:raise NoSuchPathError:
118
124
:return: git.Repo """
119
125
120
- epath = path or os .getenv ('GIT_DIR' )
126
+ self .isolated = isolated
127
+
128
+ if isolated :
129
+ if path is None :
130
+ raise ValueError ('When isolated, the repo path must be specified.' )
131
+
132
+ epath = path or os .environ .get ('GIT_DIR' )
121
133
if not epath :
122
134
epath = os .getcwd ()
123
135
if Git .is_cygwin ():
@@ -152,12 +164,12 @@ def __init__(self, path=None, odbt=GitCmdObjectDB, search_parent_directories=Fal
152
164
# If GIT_DIR is specified but none of GIT_WORK_TREE and core.worktree is specified,
153
165
# the current working directory is regarded as the top level of your working tree.
154
166
self ._working_tree_dir = os .path .dirname (self .git_dir )
155
- if os .environ .get ('GIT_COMMON_DIR' ) is None :
167
+ if isolated or os .environ .get ('GIT_COMMON_DIR' ) is None :
156
168
gitconf = self .config_reader ("repository" )
157
169
if gitconf .has_option ('core' , 'worktree' ):
158
170
self ._working_tree_dir = gitconf .get ('core' , 'worktree' )
159
- if 'GIT_WORK_TREE' in os .environ :
160
- self ._working_tree_dir = os .getenv ('GIT_WORK_TREE' )
171
+ if not isolated and 'GIT_WORK_TREE' in os .environ :
172
+ self ._working_tree_dir = os .environ . get ('GIT_WORK_TREE' )
161
173
break
162
174
163
175
dotgit = osp .join (curpath , '.git' )
@@ -204,7 +216,7 @@ def __init__(self, path=None, odbt=GitCmdObjectDB, search_parent_directories=Fal
204
216
# END working dir handling
205
217
206
218
self .working_dir = self ._working_tree_dir or self .common_dir
207
- self .git = self .GitCommandWrapperType (self .working_dir )
219
+ self .git = self .GitCommandWrapperType (self .working_dir , isolated = self . isolated )
208
220
209
221
# special handling, in special times
210
222
args = [osp .join (self .common_dir , 'objects' )]
@@ -892,7 +904,7 @@ def blame(self, rev, file, incremental=False, **kwargs):
892
904
return blames
893
905
894
906
@classmethod
895
- def init (cls , path = None , mkdir = True , odbt = GitCmdObjectDB , expand_vars = True , ** kwargs ):
907
+ def init (cls , path = None , mkdir = True , odbt = GitCmdObjectDB , expand_vars = True , isolated = False , ** kwargs ):
896
908
"""Initialize a git repository at the given path if specified
897
909
898
910
:param path:
@@ -915,6 +927,10 @@ def init(cls, path=None, mkdir=True, odbt=GitCmdObjectDB, expand_vars=True, **kw
915
927
can lead to information disclosure, allowing attackers to
916
928
access the contents of environment variables
917
929
930
+ :param isolated:
931
+ If True, the current environment variables will be isolated from git as much as possible.
932
+ Specifically the GIT_* variables are ignored as much as possible.
933
+
918
934
:param kwargs:
919
935
keyword arguments serving as additional options to the git-init command
920
936
@@ -925,12 +941,12 @@ def init(cls, path=None, mkdir=True, odbt=GitCmdObjectDB, expand_vars=True, **kw
925
941
os .makedirs (path , 0o755 )
926
942
927
943
# git command automatically chdir into the directory
928
- git = Git (path )
944
+ git = Git (path , isolated = isolated )
929
945
git .init (** kwargs )
930
946
return cls (path , odbt = odbt )
931
947
932
948
@classmethod
933
- def _clone (cls , git , url , path , odb_default_type , progress , multi_options = None , ** kwargs ):
949
+ def _clone (cls , git , url , path , odb_default_type , progress , multi_options = None , isolated = False , ** kwargs ):
934
950
if progress is not None :
935
951
progress = to_progress_instance (progress )
936
952
@@ -969,7 +985,7 @@ def _clone(cls, git, url, path, odb_default_type, progress, multi_options=None,
969
985
if not osp .isabs (path ) and git .working_dir :
970
986
path = osp .join (git ._working_dir , path )
971
987
972
- repo = cls (path , odbt = odbt )
988
+ repo = cls (path , odbt = odbt , isolated = isolated )
973
989
974
990
# retain env values that were passed to _clone()
975
991
repo .git .update_environment (** git .environment ())
@@ -985,7 +1001,7 @@ def _clone(cls, git, url, path, odb_default_type, progress, multi_options=None,
985
1001
# END handle remote repo
986
1002
return repo
987
1003
988
- def clone (self , path , progress = None , multi_options = None , ** kwargs ):
1004
+ def clone (self , path , progress = None , multi_options = None , isolated = False , ** kwargs ):
989
1005
"""Create a clone from this repository.
990
1006
991
1007
:param path: is the full path of the new repo (traditionally ends with ./<name>.git).
@@ -1000,10 +1016,10 @@ def clone(self, path, progress=None, multi_options=None, **kwargs):
1000
1016
* All remaining keyword arguments are given to the git-clone command
1001
1017
1002
1018
:return: ``git.Repo`` (the newly cloned repo)"""
1003
- return self ._clone (self .git , self .common_dir , path , type (self .odb ), progress , multi_options , ** kwargs )
1019
+ return self ._clone (self .git , self .common_dir , path , type (self .odb ), progress , multi_options , isolated , ** kwargs )
1004
1020
1005
1021
@classmethod
1006
- def clone_from (cls , url , to_path , progress = None , env = None , multi_options = None , ** kwargs ):
1022
+ def clone_from (cls , url , to_path , progress = None , env = None , multi_options = None , isolated = False , ** kwargs ):
1007
1023
"""Create a clone from the given URL
1008
1024
1009
1025
:param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS
@@ -1017,11 +1033,12 @@ def clone_from(cls, url, to_path, progress=None, env=None, multi_options=None, *
1017
1033
as its value.
1018
1034
:param multi_options: See ``clone`` method
1019
1035
:param kwargs: see the ``clone`` method
1036
+ :param isolated: see the ``clone`` method
1020
1037
:return: Repo instance pointing to the cloned directory"""
1021
- git = Git (os .getcwd ())
1038
+ git = Git (os .getcwd (), isolated = isolated )
1022
1039
if env is not None :
1023
1040
git .update_environment (** env )
1024
- return cls ._clone (git , url , to_path , GitCmdObjectDB , progress , multi_options , ** kwargs )
1041
+ return cls ._clone (git , url , to_path , GitCmdObjectDB , progress , multi_options , isolated , ** kwargs )
1025
1042
1026
1043
def archive (self , ostream , treeish = None , prefix = None , ** kwargs ):
1027
1044
"""Archive the tree at the given revision.
0 commit comments