Read-only mirror — the public repositories of the Forgejo instance, refreshed every 10 minutes. The live instance (fg.dieschoenewolke.de) is reachable only over the VPN; clone here with https://git.dieschoenewolke.de/git/<owner>/<repo>.git.
summaryrefslogtreecommitdiff
path: root/src/git-directory-helper.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/git-directory-helper.ts')
-rw-r--r--src/git-directory-helper.ts91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/git-directory-helper.ts b/src/git-directory-helper.ts
new file mode 100644
index 0000000..bfaa4a9
--- /dev/null
+++ b/src/git-directory-helper.ts
@@ -0,0 +1,91 @@
+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'
+
+export async function prepareExistingDirectory(
+ git: IGitCommandManager | undefined,
+ repositoryPath: string,
+ repositoryUrl: string,
+ clean: boolean
+): Promise<void> {
+ 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 {
+ // 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)
+ }
+
+ // Clean
+ if (clean) {
+ 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
+ }
+
+ 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))
+ }
+ }
+}