mirror of
				https://code.forgejo.org/actions/checkout.git
				synced 2025-11-04 14:49:12 +00:00 
			
		
		
		
	feat: Honor preserve-local-changes flag when repository URL changes
Makes preserve-local-changes option work consistently in all scenarios, including when repository URL changes. Updates warning message to correctly reflect this behavior.
This commit is contained in:
		
							parent
							
								
									215f9562a1
								
							
						
					
					
						commit
						45abae3e9f
					
				
					 2 changed files with 103 additions and 0 deletions
				
			
		| 
						 | 
					@ -155,6 +155,34 @@ describe('git-directory-helper tests', () => {
 | 
				
			||||||
    expect(git.tryReset).not.toHaveBeenCalled()
 | 
					    expect(git.tryReset).not.toHaveBeenCalled()
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  const preservesContentsWhenCleanFailsAndPreserveLocalChanges = 'preserves contents when clean fails and preserve-local-changes is true'
 | 
				
			||||||
 | 
					  it(preservesContentsWhenCleanFailsAndPreserveLocalChanges, async () => {
 | 
				
			||||||
 | 
					    // Arrange
 | 
				
			||||||
 | 
					    await setup(preservesContentsWhenCleanFailsAndPreserveLocalChanges)
 | 
				
			||||||
 | 
					    await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
 | 
				
			||||||
 | 
					    let mockTryClean = git.tryClean as jest.Mock<any, any>
 | 
				
			||||||
 | 
					    mockTryClean.mockImplementation(async () => {
 | 
				
			||||||
 | 
					      return false
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Act
 | 
				
			||||||
 | 
					    await gitDirectoryHelper.prepareExistingDirectory(
 | 
				
			||||||
 | 
					      git,
 | 
				
			||||||
 | 
					      repositoryPath,
 | 
				
			||||||
 | 
					      repositoryUrl,
 | 
				
			||||||
 | 
					      clean,
 | 
				
			||||||
 | 
					      ref,
 | 
				
			||||||
 | 
					      true // preserveLocalChanges = true
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Assert
 | 
				
			||||||
 | 
					    const files = await fs.promises.readdir(repositoryPath)
 | 
				
			||||||
 | 
					    expect(files.sort()).toEqual(['.git', 'my-file']) // Expect both .git and user files to remain
 | 
				
			||||||
 | 
					    expect(git.tryClean).toHaveBeenCalled()
 | 
				
			||||||
 | 
					    expect(core.warning).toHaveBeenCalled()
 | 
				
			||||||
 | 
					    expect(git.tryReset).not.toHaveBeenCalled()
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const removesContentsWhenDifferentRepositoryUrl =
 | 
					  const removesContentsWhenDifferentRepositoryUrl =
 | 
				
			||||||
    'removes contents when different repository url'
 | 
					    'removes contents when different repository url'
 | 
				
			||||||
  it(removesContentsWhenDifferentRepositoryUrl, async () => {
 | 
					  it(removesContentsWhenDifferentRepositoryUrl, async () => {
 | 
				
			||||||
| 
						 | 
					@ -182,6 +210,39 @@ describe('git-directory-helper tests', () => {
 | 
				
			||||||
    expect(git.isDetached).not.toHaveBeenCalled()
 | 
					    expect(git.isDetached).not.toHaveBeenCalled()
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const keepsContentsWhenDifferentRepositoryUrlAndPreserveLocalChanges =
 | 
				
			||||||
 | 
					    'keeps contents when different repository url and preserve-local-changes is true'
 | 
				
			||||||
 | 
					  it(keepsContentsWhenDifferentRepositoryUrlAndPreserveLocalChanges, async () => {
 | 
				
			||||||
 | 
					    // Arrange
 | 
				
			||||||
 | 
					    await setup(keepsContentsWhenDifferentRepositoryUrlAndPreserveLocalChanges)
 | 
				
			||||||
 | 
					    clean = false
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Create a file that we expect to be preserved
 | 
				
			||||||
 | 
					    await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Simulate a different repository by simply removing the .git directory
 | 
				
			||||||
 | 
					    await io.rmRF(path.join(repositoryPath, '.git'))
 | 
				
			||||||
 | 
					    await fs.promises.mkdir(path.join(repositoryPath, '.git'))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    const differentRepositoryUrl = 'https://github.com/my-different-org/my-different-repo'
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Act
 | 
				
			||||||
 | 
					    await gitDirectoryHelper.prepareExistingDirectory(
 | 
				
			||||||
 | 
					      git,
 | 
				
			||||||
 | 
					      repositoryPath,
 | 
				
			||||||
 | 
					      differentRepositoryUrl, // Use a different URL
 | 
				
			||||||
 | 
					      clean,
 | 
				
			||||||
 | 
					      ref,
 | 
				
			||||||
 | 
					      true // preserveLocalChanges = true
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Assert
 | 
				
			||||||
 | 
					    const files = await fs.promises.readdir(repositoryPath)
 | 
				
			||||||
 | 
					    console.log('Files after operation:', files)
 | 
				
			||||||
 | 
					    // When preserveLocalChanges is true, files should be preserved even with different repo URL
 | 
				
			||||||
 | 
					    expect(files.sort()).toEqual(['.git', 'my-file'].sort())
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const removesContentsWhenNoGitDirectory =
 | 
					  const removesContentsWhenNoGitDirectory =
 | 
				
			||||||
    'removes contents when no git directory'
 | 
					    'removes contents when no git directory'
 | 
				
			||||||
  it(removesContentsWhenNoGitDirectory, async () => {
 | 
					  it(removesContentsWhenNoGitDirectory, async () => {
 | 
				
			||||||
| 
						 | 
					@ -235,6 +296,34 @@ describe('git-directory-helper tests', () => {
 | 
				
			||||||
    expect(core.warning).toHaveBeenCalled()
 | 
					    expect(core.warning).toHaveBeenCalled()
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const preservesContentsWhenResetFailsAndPreserveLocalChanges = 'preserves contents when reset fails and preserve-local-changes is true'
 | 
				
			||||||
 | 
					  it(preservesContentsWhenResetFailsAndPreserveLocalChanges, async () => {
 | 
				
			||||||
 | 
					    // Arrange
 | 
				
			||||||
 | 
					    await setup(preservesContentsWhenResetFailsAndPreserveLocalChanges)
 | 
				
			||||||
 | 
					    await fs.promises.writeFile(path.join(repositoryPath, 'my-file'), '')
 | 
				
			||||||
 | 
					    let mockTryReset = git.tryReset as jest.Mock<any, any>
 | 
				
			||||||
 | 
					    mockTryReset.mockImplementation(async () => {
 | 
				
			||||||
 | 
					      return false
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Act
 | 
				
			||||||
 | 
					    await gitDirectoryHelper.prepareExistingDirectory(
 | 
				
			||||||
 | 
					      git,
 | 
				
			||||||
 | 
					      repositoryPath,
 | 
				
			||||||
 | 
					      repositoryUrl,
 | 
				
			||||||
 | 
					      clean,
 | 
				
			||||||
 | 
					      ref,
 | 
				
			||||||
 | 
					      true // preserveLocalChanges = true
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Assert
 | 
				
			||||||
 | 
					    const files = await fs.promises.readdir(repositoryPath)
 | 
				
			||||||
 | 
					    expect(files.sort()).toEqual(['.git', 'my-file']) // Expect both .git and user files to remain
 | 
				
			||||||
 | 
					    expect(git.tryClean).toHaveBeenCalled()
 | 
				
			||||||
 | 
					    expect(git.tryReset).toHaveBeenCalled()
 | 
				
			||||||
 | 
					    expect(core.warning).toHaveBeenCalled()
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const removesContentsWhenUndefinedGitCommandManager =
 | 
					  const removesContentsWhenUndefinedGitCommandManager =
 | 
				
			||||||
    'removes contents when undefined git command manager'
 | 
					    'removes contents when undefined git command manager'
 | 
				
			||||||
  it(removesContentsWhenUndefinedGitCommandManager, async () => {
 | 
					  it(removesContentsWhenUndefinedGitCommandManager, async () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,20 @@ export async function prepareExistingDirectory(
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Check repository conditions
 | 
				
			||||||
 | 
					  let isLocalGitRepo = git && fsHelper.directoryExistsSync(path.join(repositoryPath, '.git'));
 | 
				
			||||||
 | 
					  let repoUrl = isLocalGitRepo ? await git?.tryGetFetchUrl() : '';
 | 
				
			||||||
 | 
					  let isSameRepository = repositoryUrl === repoUrl;
 | 
				
			||||||
 | 
					  let differentRepoUrl = !isSameRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Repository URL has changed
 | 
				
			||||||
 | 
					  if (differentRepoUrl) {
 | 
				
			||||||
 | 
					    if (preserveLocalChanges) {
 | 
				
			||||||
 | 
					      core.warning(`Repository URL has changed from '${repoUrl}' to '${repositoryUrl}'. Local changes will be preserved as requested.`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    remove = true; // Mark for removal, but actual removal will respect preserveLocalChanges
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (remove && !preserveLocalChanges) {
 | 
					  if (remove && !preserveLocalChanges) {
 | 
				
			||||||
    // Delete the contents of the directory. Don't delete the directory itself
 | 
					    // Delete the contents of the directory. Don't delete the directory itself
 | 
				
			||||||
    // since it might be the current working directory.
 | 
					    // since it might be the current working directory.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue