66 "io"
77 "os"
88 "path/filepath"
9+ "regexp"
910 "runtime"
1011 "strings"
1112 "testing"
@@ -15,6 +16,7 @@ import (
1516 "github.com/go-git/go-billy/v5/util"
1617 fixtures "github.com/go-git/go-git-fixtures/v4"
1718 "github.com/go-git/go-git/v5/plumbing"
19+ "github.com/stretchr/testify/assert"
1820 . "gopkg.in/check.v1"
1921)
2022
@@ -810,53 +812,139 @@ func (s *SuiteDotGit) TestPackRefs(c *C) {
810812 c .Assert (ref .Hash ().String (), Equals , "b8d3ffab552895c19b9fcf7aa264d277cde33881" )
811813}
812814
813- func ( s * SuiteDotGit ) TestAlternates ( c * C ) {
814- fs , clean := s . TemporalFilesystem ()
815- defer clean ( )
815+ func TestAlternatesDefault ( t * testing. T ) {
816+ // Create a new dotgit object.
817+ dotFS := osfs . New ( t . TempDir () )
816818
817- // Create a new dotgit object and initialize.
818- dir := New (fs )
819- err := dir .Initialize ()
820- c .Assert (err , IsNil )
819+ testAlternates (t , dotFS , dotFS )
820+ }
821821
822- // Create alternates file.
823- altpath := fs . Join ( "objects" , "info" , " alternates" )
824- f , err := fs . Create ( altpath )
825- c . Assert ( err , IsNil )
822+ func TestAlternatesWithFS ( t * testing. T ) {
823+ // Create a new dotgit object with a specific FS for alternates.
824+ altFS := osfs . New ( t . TempDir () )
825+ dotFS , _ := altFS . Chroot ( "repo2" )
826826
827- // Multiple alternates.
828- var strContent string
829- if runtime .GOOS == "windows" {
830- strContent = "C:\\ Users\\ username\\ repo1\\ .git\\ objects\r \n ..\\ ..\\ ..\\ rep2\\ .git\\ objects"
831- } else {
832- strContent = "/Users/username/rep1//.git/objects\n ../../../rep2//.git/objects"
827+ testAlternates (t , dotFS , altFS )
828+ }
829+
830+ func TestAlternatesWithBoundOS (t * testing.T ) {
831+ // Create a new dotgit object with a specific FS for alternates.
832+ altFS := osfs .New (t .TempDir (), osfs .WithBoundOS ())
833+ dotFS , _ := altFS .Chroot ("repo2" )
834+
835+ testAlternates (t , dotFS , altFS )
836+ }
837+
838+ func testAlternates (t * testing.T , dotFS , altFS billy.Filesystem ) {
839+ tests := []struct {
840+ name string
841+ in []string
842+ inWindows []string
843+ setup func ()
844+ wantErr bool
845+ wantRoots []string
846+ }{
847+ {
848+ name : "no alternates" ,
849+ },
850+ {
851+ name : "abs path" ,
852+ in : []string {filepath .Join (altFS .Root (), "./repo1/.git/objects" )},
853+ inWindows : []string {filepath .Join (altFS .Root (), ".\\ repo1\\ .git\\ objects" )},
854+ setup : func () {
855+ err := altFS .MkdirAll (filepath .Join ("repo1" , ".git" , "objects" ), 0o700 )
856+ assert .NoError (t , err )
857+ },
858+ wantRoots : []string {filepath .Join ("repo1" , ".git" )},
859+ },
860+ {
861+ name : "rel path" ,
862+ in : []string {"../../../repo3//.git/objects" },
863+ inWindows : []string {"..\\ ..\\ ..\\ repo3\\ .git\\ objects" },
864+ setup : func () {
865+ err := altFS .MkdirAll (filepath .Join ("repo3" , ".git" , "objects" ), 0o700 )
866+ assert .NoError (t , err )
867+ },
868+ wantRoots : []string {filepath .Join ("repo3" , ".git" )},
869+ },
870+ {
871+ name : "invalid abs path" ,
872+ in : []string {"/alt/target2" },
873+ inWindows : []string {"\\ alt\\ target2" },
874+ wantErr : true ,
875+ },
876+ {
877+ name : "invalid rel path" ,
878+ in : []string {"../../../alt/target3" },
879+ inWindows : []string {"..\\ ..\\ ..\\ alt\\ target3" },
880+ wantErr : true ,
881+ },
833882 }
834- content := []byte (strContent )
835- f .Write (content )
836- f .Close ()
837883
838- dotgits , err := dir .Alternates ()
839- c .Assert (err , IsNil )
840- if runtime .GOOS == "windows" {
841- c .Assert (dotgits [0 ].fs .Root (), Equals , "C:\\ Users\\ username\\ repo1\\ .git" )
842- } else {
843- c .Assert (dotgits [0 ].fs .Root (), Equals , "/Users/username/rep1/.git" )
884+ for _ , tc := range tests {
885+ t .Run (tc .name , func (t * testing.T ) {
886+ dir := NewWithOptions (dotFS , Options {AlternatesFS : altFS })
887+ err := dir .Initialize ()
888+ assert .NoError (t , err )
889+
890+ content := strings .Join (tc .in , "\n " )
891+ if runtime .GOOS == "windows" {
892+ content = strings .Join (tc .inWindows , "\r \n " )
893+ }
894+
895+ // Create alternates file.
896+ altpath := dotFS .Join ("objects" , "info" , "alternates" )
897+ f , err := dotFS .Create (altpath )
898+ assert .NoError (t , err )
899+ f .Write ([]byte (content ))
900+ f .Close ()
901+
902+ if tc .setup != nil {
903+ tc .setup ()
904+ }
905+
906+ dotgits , err := dir .Alternates ()
907+ if tc .wantErr {
908+ assert .Error (t , err )
909+ } else {
910+ assert .NoError (t , err )
911+ }
912+
913+ for i , d := range dotgits {
914+ assert .Regexp (t , "^" + regexp .QuoteMeta (altFS .Root ()), d .fs .Root ())
915+ assert .Regexp (t , regexp .QuoteMeta (tc .wantRoots [i ])+ "$" , d .fs .Root ())
916+ }
917+ })
844918 }
919+ }
845920
846- // For relative path:
847- // /some/absolute/path/to/dot-git -> /some/absolute/path
848- pathx := strings .Split (fs .Root (), string (filepath .Separator ))
849- pathx = pathx [:len (pathx )- 2 ]
850- // Use string.Join() to avoid malformed absolutepath on windows
851- // C:Users\\User\\... instead of C:\\Users\\appveyor\\... .
852- resolvedPath := strings .Join (pathx , string (filepath .Separator ))
853- // Append the alternate path to the resolvedPath
854- expectedPath := fs .Join (string (filepath .Separator ), resolvedPath , "rep2" , ".git" )
921+ func TestAlternatesDupes (t * testing.T ) {
922+ dotFS := osfs .New (t .TempDir ())
923+ dir := New (dotFS )
924+ err := dir .Initialize ()
925+ assert .NoError (t , err )
926+
927+ path := filepath .Join (dotFS .Root (), "target3" )
928+ dupes := []string {path , path , path , path , path }
929+
930+ content := strings .Join (dupes , "\n " )
855931 if runtime .GOOS == "windows" {
856- expectedPath = fs .Join (resolvedPath , "rep2" , ".git " )
932+ content = strings .Join (dupes , "\r \n " )
857933 }
858934
859- c .Assert (dotgits [1 ].fs .Root (), Equals , expectedPath )
935+ err = dotFS .MkdirAll ("target3" , 0o700 )
936+ assert .NoError (t , err )
937+
938+ // Create alternates file.
939+ altpath := dotFS .Join ("objects" , "info" , "alternates" )
940+ f , err := dotFS .Create (altpath )
941+ assert .NoError (t , err )
942+ f .Write ([]byte (content ))
943+ f .Close ()
944+
945+ dotgits , err := dir .Alternates ()
946+ assert .NoError (t , err )
947+ assert .Len (t , dotgits , 1 )
860948}
861949
862950type norwfs struct {
0 commit comments