diff --git a/modules/annex/annex.go b/modules/annex/annex.go index 7b499fe3f1..9a70612a1e 100644 --- a/modules/annex/annex.go +++ b/modules/annex/annex.go @@ -20,6 +20,7 @@ import ( "strings" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" ) @@ -100,6 +101,14 @@ var ( repoPath2uuidCache = make(map[string]string) ) +func Init() error { + if !setting.Annex.Enabled { + return nil + } + log.Info("Populating the git-annex UUID cache with existing repositories") + return updateUUID2RepoPathCache() +} + func updateUUID2RepoPathCache() error { return filepath.WalkDir(setting.RepoRootPath, func(path string, d fs.DirEntry, err error) error { if err == nil && repoConfigFileRe.MatchString(path) { @@ -122,7 +131,7 @@ func updateUUID2RepoPathCache() error { }) } -func UUID2RepoPath(uuid string) (string, error) { +func repoPathFromUUIDCache(uuid string) (string, error) { if repoPath, ok := uuid2repoPathCache[uuid]; ok { return repoPath, nil } @@ -135,3 +144,37 @@ func UUID2RepoPath(uuid string) (string, error) { } return "", fmt.Errorf("no repository known for UUID '%s'", uuid) } + +func checkValidity(uuid, repoPath string) (bool, error) { + stdout, _, err := git.NewCommand(git.DefaultContext, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: repoPath}) + if err != nil { + return false, err + } + repoUUID := strings.TrimSpace(stdout) + return uuid == repoUUID, nil +} + +func removeCachedEntries(uuid, repoPath string) { + delete(uuid2repoPathCache, uuid) + delete(repoPath2uuidCache, repoPath) +} + +func UUID2RepoPath(uuid string) (string, error) { + // Get the current cache entry for the UUID + repoPath, err := repoPathFromUUIDCache(uuid) + if err != nil { + return "", err + } + // Check if it is still up-to-date + valid, err := checkValidity(uuid, repoPath) + if err != nil { + return "", err + } + if !valid { + // If it isn't, remove the cache entry and try again + removeCachedEntries(uuid, repoPath) + return UUID2RepoPath(uuid) + } + // Otherwise just return the cached entry + return repoPath, nil +} diff --git a/routers/init.go b/routers/init.go index 821a0ef38c..d881edd030 100644 --- a/routers/init.go +++ b/routers/init.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models" asymkey_model "code.gitea.io/gitea/models/asymkey" authmodel "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/modules/annex" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/eventsource" "code.gitea.io/gitea/modules/git" @@ -167,6 +168,8 @@ func InitWebInstalled(ctx context.Context) { actions_service.Init() + mustInit(annex.Init) + // Finally start up the cron cron.NewContext(ctx) }