77import io
88import os
99import os .path as osp
10+ import sys
1011from unittest import mock
1112
1213import pytest
@@ -430,6 +431,7 @@ def test_multiple_include_paths_with_same_key(self, rw_dir):
430431 def test_conditional_includes_from_git_dir (self , rw_dir ):
431432 # Initiate repository path.
432433 git_dir = osp .join (rw_dir , "target1" , "repo1" )
434+ git_dir_pattern = git_dir .replace ("\\ " , "/" )
433435 os .makedirs (git_dir )
434436
435437 # Initiate mocked repository.
@@ -441,37 +443,42 @@ def test_conditional_includes_from_git_dir(self, rw_dir):
441443 template = '[includeIf "{}:{}"]\n path={}\n '
442444
443445 with open (path1 , "w" ) as stream :
446+ # on Windows, this writes a backslash pattern.
444447 stream .write (template .format ("gitdir" , git_dir , path2 ))
445448
446449 # Ensure that config is ignored if no repo is set.
447450 with GitConfigParser (path1 ) as config :
448451 assert not config ._has_includes ()
449452 assert config ._included_paths () == []
450453
451- # Ensure that config is included if path is matching git_dir.
452- with GitConfigParser (path1 , repo = repo ) as config :
453- assert config ._has_includes ()
454- assert config ._included_paths () == [("path" , path2 )]
454+ # Git uses forward slashes in gitdir patterns on every platform:
455+ # backslashes escape the next pattern character rather than separate
456+ # path components. On Windows, GitPython therefore normalizes git_dir
457+ # to forward slashes but leaves this backslash pattern unchanged, so
458+ # the two do not match and no path is included.
459+ with GitConfigParser (path1 , repo = repo , merge_includes = False ) as config :
460+ expected_paths = [] if sys .platform == "win32" else [("path" , path2 )]
461+ assert config ._included_paths () == expected_paths
455462
456463 # Ensure that Git's forward-slash syntax matches native Windows paths.
457464 with open (path1 , "w" ) as stream :
458- stream .write (template .format ("gitdir" , git_dir . replace ( " \\ " , "/" ) , path2 ))
465+ stream .write (template .format ("gitdir" , git_dir_pattern , path2 ))
459466
460467 with GitConfigParser (path1 , repo = repo ) as config :
461468 assert config ._has_includes ()
462469 assert config ._included_paths () == [("path" , path2 )]
463470
464471 # Ensure that config is ignored if case is incorrect.
465472 with open (path1 , "w" ) as stream :
466- stream .write (template .format ("gitdir" , git_dir .upper (), path2 ))
473+ stream .write (template .format ("gitdir" , git_dir_pattern .upper (), path2 ))
467474
468475 with GitConfigParser (path1 , repo = repo ) as config :
469476 assert not config ._has_includes ()
470477 assert config ._included_paths () == []
471478
472479 # Ensure that config is included if case is ignored.
473480 with open (path1 , "w" ) as stream :
474- stream .write (template .format ("gitdir/i" , git_dir .upper (), path2 ))
481+ stream .write (template .format ("gitdir/i" , git_dir_pattern .upper (), path2 ))
475482
476483 with GitConfigParser (path1 , repo = repo ) as config :
477484 assert config ._has_includes ()
@@ -501,6 +508,20 @@ def test_conditional_includes_from_git_dir(self, rw_dir):
501508 assert config ._has_includes ()
502509 assert config ._included_paths () == [("path" , path2 )]
503510
511+ @with_rw_directory
512+ def test_conditional_includes_do_not_treat_backslashes_as_separators (self , rw_dir ):
513+ git_dir = osp .join (rw_dir , "target" , "repo" )
514+ repo = mock .Mock (git_dir = git_dir )
515+ config_path = osp .join (rw_dir , "config" )
516+ included_path = osp .join (rw_dir , "included" )
517+ pattern = git_dir .replace ("\\ " , "/" ).replace ("/target/repo" , R"/target\repo" )
518+
519+ with open (config_path , "w" ) as stream :
520+ stream .write (f'[includeIf "gitdir:{ pattern } "]\n path={ included_path } \n ' )
521+
522+ with GitConfigParser (config_path , repo = repo , merge_includes = False ) as config :
523+ assert config ._included_paths () == []
524+
504525 @with_rw_directory
505526 def test_conditional_includes_from_branch_name (self , rw_dir ):
506527 # Initiate mocked branch.
0 commit comments