@@ -134,6 +134,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable):
134134 """
135135
136136 unsafe_git_checkout_index_options = ["--prefix" ]
137+ unsafe_git_read_tree_options = ["--index-output" ]
137138
138139 __slots__ = ("repo" , "version" , "entries" , "_extension_data" , "_file_path" )
139140
@@ -259,7 +260,12 @@ def write(
259260
260261 @post_clear_cache
261262 @default_index
262- def merge_tree (self , rhs : Treeish , base : Union [None , Treeish ] = None ) -> "IndexFile" :
263+ def merge_tree (
264+ self ,
265+ rhs : Treeish ,
266+ base : Union [None , Treeish ] = None ,
267+ allow_unsafe_options : bool = False ,
268+ ) -> "IndexFile" :
263269 """Merge the given `rhs` treeish into the current index, possibly taking
264270 a common base treeish into account.
265271
@@ -273,6 +279,9 @@ def merge_tree(self, rhs: Treeish, base: Union[None, Treeish] = None) -> "IndexF
273279 Optional treeish reference pointing to the common base of `rhs` and this
274280 index which equals lhs.
275281
282+ :param allow_unsafe_options:
283+ Allow options that may write to arbitrary paths.
284+
276285 :return:
277286 self (containing the merge and possibly unmerged entries in case of
278287 conflicts)
@@ -283,6 +292,12 @@ def merge_tree(self, rhs: Treeish, base: Union[None, Treeish] = None) -> "IndexF
283292 yourself, you have to commit the changed index (or make a valid tree from
284293 it) and retry with a three-way :meth:`index.from_tree <from_tree>` call.
285294 """
295+ if not allow_unsafe_options :
296+ Git .check_unsafe_options (
297+ options = Git ._option_candidates ([base , rhs ]),
298+ unsafe_options = self .unsafe_git_read_tree_options ,
299+ )
300+
286301 # -i : ignore working tree status
287302 # --aggressive : handle more merge cases
288303 # -m : do an actual merge
@@ -327,7 +342,13 @@ def new(cls, repo: "Repo", *tree_sha: Union[str, Tree]) -> "IndexFile":
327342 return inst
328343
329344 @classmethod
330- def from_tree (cls , repo : "Repo" , * treeish : Treeish , ** kwargs : Any ) -> "IndexFile" :
345+ def from_tree (
346+ cls ,
347+ repo : "Repo" ,
348+ * treeish : Treeish ,
349+ allow_unsafe_options : bool = False ,
350+ ** kwargs : Any ,
351+ ) -> "IndexFile" :
331352 R"""Merge the given treeish revisions into a new index which is returned.
332353 The original index will remain unaltered.
333354
@@ -351,6 +372,9 @@ def from_tree(cls, repo: "Repo", *treeish: Treeish, **kwargs: Any) -> "IndexFile
351372 :param kwargs:
352373 Additional arguments passed to :manpage:`git-read-tree(1)`.
353374
375+ :param allow_unsafe_options:
376+ Allow options that may write to arbitrary paths.
377+
354378 :return:
355379 New :class:`IndexFile` instance. It will point to a temporary index location
356380 which does not exist anymore. If you intend to write such a merged Index,
@@ -368,6 +392,12 @@ def from_tree(cls, repo: "Repo", *treeish: Treeish, **kwargs: Any) -> "IndexFile
368392 if len (treeish ) == 0 or len (treeish ) > 3 :
369393 raise ValueError ("Please specify between 1 and 3 treeish, got %i" % len (treeish ))
370394
395+ if not allow_unsafe_options :
396+ Git .check_unsafe_options (
397+ options = Git ._option_candidates (treeish , kwargs ),
398+ unsafe_options = cls .unsafe_git_read_tree_options ,
399+ )
400+
371401 arg_list : List [Union [Treeish , str ]] = []
372402 # Ignore that the working tree and index possibly are out of date.
373403 if len (treeish ) > 1 :
@@ -994,6 +1024,7 @@ def remove(
9941024 self ,
9951025 items : Union [PathLike , Sequence [Union [PathLike , Blob , BaseIndexEntry , "Submodule" ]]],
9961026 working_tree : bool = False ,
1027+ allow_unsafe_options : bool = False ,
9971028 ** kwargs : Any ,
9981029 ) -> List [str ]:
9991030 R"""Remove the given items from the index and optionally from the working tree
@@ -1024,6 +1055,10 @@ def remove(
10241055 physically removing the respective file. This may fail if there are
10251056 uncommitted changes in it.
10261057
1058+ :param allow_unsafe_options:
1059+ Allow unsafe options such as ``--pathspec-from-file`` to be passed to
1060+ :manpage:`git-rm(1)`.
1061+
10271062 :param kwargs:
10281063 Additional keyword arguments to be passed to :manpage:`git-rm(1)`, such as
10291064 ``r`` to allow recursive removal.
@@ -1035,6 +1070,11 @@ def remove(
10351070 This is interesting to know in case you have provided a directory or globs.
10361071 Paths are relative to the repository.
10371072 """
1073+ if not allow_unsafe_options :
1074+ Git .check_unsafe_options (
1075+ options = Git ._option_candidates ([], kwargs ),
1076+ unsafe_options = Git .unsafe_git_pathspec_from_file_options ,
1077+ )
10381078 args = []
10391079 if not working_tree :
10401080 args .append ("--cached" )
@@ -1416,6 +1456,7 @@ def reset(
14161456 working_tree : bool = False ,
14171457 paths : Union [None , Iterable [PathLike ]] = None ,
14181458 head : bool = False ,
1459+ allow_unsafe_options : bool = False ,
14191460 ** kwargs : Any ,
14201461 ) -> "IndexFile" :
14211462 """Reset the index to reflect the tree at the given commit. This will not adjust
@@ -1447,6 +1488,9 @@ def reset(
14471488 The paths need to exist at the commit, otherwise an exception will be
14481489 raised.
14491490
1491+ :param allow_unsafe_options:
1492+ Allow options that may write to arbitrary paths.
1493+
14501494 :param kwargs:
14511495 Additional keyword arguments passed to :manpage:`git-reset(1)`.
14521496
@@ -1463,7 +1507,7 @@ def reset(
14631507 """
14641508 # What we actually want to do is to merge the tree into our existing index,
14651509 # which is what git-read-tree does.
1466- new_inst = type (self ).from_tree (self .repo , commit )
1510+ new_inst = type (self ).from_tree (self .repo , commit , allow_unsafe_options = allow_unsafe_options )
14671511 if not paths :
14681512 self .entries = new_inst .entries
14691513 else :
0 commit comments