git-directory-helper.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import * as core from '@actions/core'
  2. import * as fs from 'fs'
  3. import * as fsHelper from './fs-helper'
  4. import * as io from '@actions/io'
  5. import * as path from 'path'
  6. import {IGitCommandManager} from './git-command-manager'
  7. export async function prepareExistingDirectory(
  8. git: IGitCommandManager | undefined,
  9. repositoryPath: string,
  10. repositoryUrl: string,
  11. clean: boolean
  12. ): Promise<void> {
  13. let remove = false
  14. // Check whether using git or REST API
  15. if (!git) {
  16. remove = true
  17. }
  18. // Fetch URL does not match
  19. else if (
  20. !fsHelper.directoryExistsSync(path.join(repositoryPath, '.git')) ||
  21. repositoryUrl !== (await git.tryGetFetchUrl())
  22. ) {
  23. remove = true
  24. } else {
  25. // Delete any index.lock and shallow.lock left by a previously canceled run or crashed git process
  26. const lockPaths = [
  27. path.join(repositoryPath, '.git', 'index.lock'),
  28. path.join(repositoryPath, '.git', 'shallow.lock')
  29. ]
  30. for (const lockPath of lockPaths) {
  31. try {
  32. await io.rmRF(lockPath)
  33. } catch (error) {
  34. core.debug(`Unable to delete '${lockPath}'. ${error.message}`)
  35. }
  36. }
  37. try {
  38. // Checkout detached HEAD
  39. if (!(await git.isDetached())) {
  40. await git.checkoutDetach()
  41. }
  42. // Remove all refs/heads/*
  43. let branches = await git.branchList(false)
  44. for (const branch of branches) {
  45. await git.branchDelete(false, branch)
  46. }
  47. // Remove all refs/remotes/origin/* to avoid conflicts
  48. branches = await git.branchList(true)
  49. for (const branch of branches) {
  50. await git.branchDelete(true, branch)
  51. }
  52. // Clean
  53. if (clean) {
  54. if (!(await git.tryClean())) {
  55. core.debug(
  56. `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}'.`
  57. )
  58. remove = true
  59. } else if (!(await git.tryReset())) {
  60. remove = true
  61. }
  62. if (remove) {
  63. core.warning(
  64. `Unable to clean or reset the repository. The repository will be recreated instead.`
  65. )
  66. }
  67. }
  68. } catch (error) {
  69. core.warning(
  70. `Unable to prepare the existing repository. The repository will be recreated instead.`
  71. )
  72. remove = true
  73. }
  74. }
  75. if (remove) {
  76. // Delete the contents of the directory. Don't delete the directory itself
  77. // since it might be the current working directory.
  78. core.info(`Deleting the contents of '${repositoryPath}'`)
  79. for (const file of await fs.promises.readdir(repositoryPath)) {
  80. await io.rmRF(path.join(repositoryPath, file))
  81. }
  82. }
  83. }