mirror of
				https://github.com/actions/checkout.git
				synced 2025-11-04 04:44:21 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			102 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import * as assert from 'assert'
 | 
						|
import * as core from '@actions/core'
 | 
						|
import * as fs from 'fs'
 | 
						|
import * as fsHelper from './fs-helper'
 | 
						|
import * as io from '@actions/io'
 | 
						|
import * as path from 'path'
 | 
						|
import {IGitCommandManager} from './git-command-manager'
 | 
						|
import {IGitSourceSettings} from './git-source-settings'
 | 
						|
 | 
						|
export async function prepareExistingDirectory(
 | 
						|
  git: IGitCommandManager | undefined,
 | 
						|
  repositoryPath: string,
 | 
						|
  repositoryUrl: string,
 | 
						|
  clean: boolean
 | 
						|
): Promise<void> {
 | 
						|
  assert.ok(repositoryPath, 'Expected repositoryPath to be defined')
 | 
						|
  assert.ok(repositoryUrl, 'Expected repositoryUrl to be defined')
 | 
						|
 | 
						|
  // Indicates whether to delete the directory contents
 | 
						|
  let remove = false
 | 
						|
 | 
						|
  // Check whether using git or REST API
 | 
						|
  if (!git) {
 | 
						|
    remove = true
 | 
						|
  }
 | 
						|
  // Fetch URL does not match
 | 
						|
  else if (
 | 
						|
    !fsHelper.directoryExistsSync(path.join(repositoryPath, '.git')) ||
 | 
						|
    repositoryUrl !== (await git.tryGetFetchUrl())
 | 
						|
  ) {
 | 
						|
    remove = true
 | 
						|
  } else {
 | 
						|
    // Delete any index.lock and shallow.lock left by a previously canceled run or crashed git process
 | 
						|
    const lockPaths = [
 | 
						|
      path.join(repositoryPath, '.git', 'index.lock'),
 | 
						|
      path.join(repositoryPath, '.git', 'shallow.lock')
 | 
						|
    ]
 | 
						|
    for (const lockPath of lockPaths) {
 | 
						|
      try {
 | 
						|
        await io.rmRF(lockPath)
 | 
						|
      } catch (error) {
 | 
						|
        core.debug(`Unable to delete '${lockPath}'. ${error.message}`)
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    try {
 | 
						|
      core.startGroup('Removing previously created refs, to avoid conflicts')
 | 
						|
      // Checkout detached HEAD
 | 
						|
      if (!(await git.isDetached())) {
 | 
						|
        await git.checkoutDetach()
 | 
						|
      }
 | 
						|
 | 
						|
      // Remove all refs/heads/*
 | 
						|
      let branches = await git.branchList(false)
 | 
						|
      for (const branch of branches) {
 | 
						|
        await git.branchDelete(false, branch)
 | 
						|
      }
 | 
						|
 | 
						|
      // Remove all refs/remotes/origin/* to avoid conflicts
 | 
						|
      branches = await git.branchList(true)
 | 
						|
      for (const branch of branches) {
 | 
						|
        await git.branchDelete(true, branch)
 | 
						|
      }
 | 
						|
      core.endGroup()
 | 
						|
 | 
						|
      // Clean
 | 
						|
      if (clean) {
 | 
						|
        core.startGroup('Cleaning the repository')
 | 
						|
        if (!(await git.tryClean())) {
 | 
						|
          core.debug(
 | 
						|
            `The clean command failed. This might be caused by: 1) path too long, 2) permission issue, or 3) file in use. For futher investigation, manually run 'git clean -ffdx' on the directory '${repositoryPath}'.`
 | 
						|
          )
 | 
						|
          remove = true
 | 
						|
        } else if (!(await git.tryReset())) {
 | 
						|
          remove = true
 | 
						|
        }
 | 
						|
        core.endGroup()
 | 
						|
 | 
						|
        if (remove) {
 | 
						|
          core.warning(
 | 
						|
            `Unable to clean or reset the repository. The repository will be recreated instead.`
 | 
						|
          )
 | 
						|
        }
 | 
						|
      }
 | 
						|
    } catch (error) {
 | 
						|
      core.warning(
 | 
						|
        `Unable to prepare the existing repository. The repository will be recreated instead.`
 | 
						|
      )
 | 
						|
      remove = true
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (remove) {
 | 
						|
    // Delete the contents of the directory. Don't delete the directory itself
 | 
						|
    // since it might be the current working directory.
 | 
						|
    core.info(`Deleting the contents of '${repositoryPath}'`)
 | 
						|
    for (const file of await fs.promises.readdir(repositoryPath)) {
 | 
						|
      await io.rmRF(path.join(repositoryPath, file))
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |