@@ -84,7 +84,7 @@ func TestResolveTag(t *testing.T) {
8484 } {
8585 testName := fmt .Sprintf ("%s, %s" , testTable .objectTypeName , annotationConfig .descriptor )
8686 tag := makeTag (t , repository , testName , testTable .objectHash , annotationConfig .annotated )
87- resolvedTag , err := ResolveTag (tag , repository )
87+ resolvedTag , err := resolveTag (tag , repository )
8888 testTable .errorAssertion (t , err , fmt .Sprintf ("%s tag resolution error" , testName ))
8989 if err == nil {
9090 assert .Equal (t , testTable .objectHash , * resolvedTag , fmt .Sprintf ("%s tag resolution" , testName ))
@@ -139,9 +139,69 @@ func TestSortedCommitTags(t *testing.T) {
139139 assert .Equal (t , tags , sorted )
140140}
141141
142+ func TestCheckoutTag (t * testing.T ) {
143+ // Create a folder for the test repository.
144+ repositoryPath , err := paths .TempDir ().MkTempDir ("gitutils-TestCheckoutTag-repo" )
145+ require .NoError (t , err )
146+
147+ // Create test repository.
148+ repository , err := git .PlainInit (repositoryPath .String (), false )
149+ require .NoError (t , err )
150+
151+ // Generate meaningless commit history, creating some tags along the way.
152+ var tags []* plumbing.Reference
153+ tags = append (tags , makeTag (t , repository , "1.0.0" , makeCommit (t , repository , repositoryPath ), true ))
154+ makeCommit (t , repository , repositoryPath )
155+ makeCommit (t , repository , repositoryPath )
156+ tags = append (tags , makeTag (t , repository , "1.0.1" , makeCommit (t , repository , repositoryPath ), true ))
157+ makeCommit (t , repository , repositoryPath )
158+ makeTag (t , repository , "tree-tag" , getTreeHash (t , repository ), true )
159+ tags = append (tags , makeTag (t , repository , "1.0.2" , makeCommit (t , repository , repositoryPath ), true ))
160+ makeTag (t , repository , "blob-tag" , getBlobHash (t , repository ), true )
161+ trackedFilePath , _ := commitFile (t , repository , repositoryPath )
162+
163+ for _ , tag := range tags {
164+ // Put the repository into a dirty state.
165+ // Add an untracked file.
166+ _ , err = paths .WriteToTempFile ([]byte {}, repositoryPath , "gitutils-TestCheckoutTag-tempfile" )
167+ require .NoError (t , err )
168+ // Modify a tracked file.
169+ err = trackedFilePath .WriteFile ([]byte {42 })
170+ require .NoError (t , err )
171+ // Create empty folder.
172+ emptyFolderPath , err := repositoryPath .MkTempDir ("gitutils-TestCheckoutTag-emptyFolder" )
173+ require .NoError (t , err )
174+
175+ err = CheckoutTag (repository , tag )
176+ assert .NoError (t , err , fmt .Sprintf ("Checking out tag %s" , tag ))
177+
178+ expectedHash , err := resolveTag (tag , repository )
179+ require .NoError (t , err )
180+ headRef , err := repository .Head ()
181+ require .NoError (t , err )
182+ assert .Equal (t , * expectedHash , headRef .Hash (), "HEAD is at tag" )
183+
184+ // Check if cleanup was successful.
185+ tree , err := repository .Worktree ()
186+ require .NoError (t , err )
187+ status , err := tree .Status ()
188+ require .NoError (t , err )
189+ assert .True (t , status .IsClean (), "Repository is clean" )
190+ emptyFolderExists , err := emptyFolderPath .ExistCheck ()
191+ require .NoError (t , err )
192+ assert .False (t , emptyFolderExists , "Empty folder was removed" )
193+ }
194+ }
195+
142196// makeCommit creates a test commit in the given repository and returns its plumbing.Hash object.
143197func makeCommit (t * testing.T , repository * git.Repository , repositoryPath * paths.Path ) plumbing.Hash {
144- _ , err := paths .WriteToTempFile ([]byte {}, repositoryPath , "gitutils-makeCommit-tempfile" )
198+ _ , hash := commitFile (t , repository , repositoryPath )
199+ return hash
200+ }
201+
202+ // commitFile commits a file in the given repository and returns its path and the commit's plumbing.Hash object.
203+ func commitFile (t * testing.T , repository * git.Repository , repositoryPath * paths.Path ) (* paths.Path , plumbing.Hash ) {
204+ filePath , err := paths .WriteToTempFile ([]byte {}, repositoryPath , "gitutils-makeCommit-tempfile" )
145205 require .Nil (t , err )
146206
147207 worktree , err := repository .Worktree ()
@@ -163,7 +223,7 @@ func makeCommit(t *testing.T, repository *git.Repository, repositoryPath *paths.
163223 )
164224 require .Nil (t , err )
165225
166- return commit
226+ return filePath , commit
167227}
168228
169229// getTreeHash returns the plumbing.Hash object for an arbitrary Git tree object.
0 commit comments