@@ -1066,11 +1066,12 @@ def remove(
10661066
10671067 - :class:`~git.objects.blob.Blob` object
10681068
1069- Only the path portion is used in this case.
1069+ Only the path portion is used in this case. It is matched literally.
10701070
10711071 - :class:`~git.index.typ.BaseIndexEntry` or compatible type
10721072
1073- The only relevant information here is the path. The stage is ignored.
1073+ The only relevant information here is the path, which is matched
1074+ literally. The stage is ignored.
10741075
10751076 :param working_tree:
10761077 If ``True``, the entry will also be removed from the working tree,
@@ -1107,8 +1108,17 @@ def remove(
11071108 args .append ("--cached" )
11081109 args .append ("--" )
11091110
1110- # Preprocess paths.
1111- paths = list (map (os .fspath , self ._items_to_rela_paths (items ))) # type: ignore[arg-type]
1111+ # Preprocess paths. Entries, blobs and submodules name exact paths, which Git
1112+ # must not expand as patterns. Path strings keep their pathspec semantics.
1113+ if isinstance (items , (str , os .PathLike )):
1114+ items = [items ]
1115+ item_list = list (items )
1116+ paths = [
1117+ ":(literal)" + os .fspath (rela_path )
1118+ if isinstance (item , (BaseIndexEntry , Blob , Submodule ))
1119+ else os .fspath (rela_path )
1120+ for item , rela_path in zip (item_list , self ._items_to_rela_paths (item_list ))
1121+ ]
11121122 with self ._materialized_index () as path :
11131123 removed_paths = self .repo .git ._call_process_safe (
11141124 "rm" , args , paths , env = {"GIT_INDEX_FILE" : path }, ** kwargs
0 commit comments