diff --git a/backend/LexBoxApi/Services/HgService.cs b/backend/LexBoxApi/Services/HgService.cs index 8aa3d17ec9..f48bbf586b 100644 --- a/backend/LexBoxApi/Services/HgService.cs +++ b/backend/LexBoxApi/Services/HgService.cs @@ -229,7 +229,7 @@ public async Task CleanupResetBackups(bool dryRun = false) /// - /// deletes all files and folders in the repo folder except for .hg + /// deletes all files and folders in the repo folder except for .hg, and drops .hg/hgrc /// private async Task CleanupRepoFolder(DirectoryInfo repoDir) { @@ -237,7 +237,13 @@ await Task.Run(() => { foreach (var info in repoDir.EnumerateFileSystemInfos()) { - if (info.Name == ".hg") continue; + if (info.Name == ".hg") + { + // Mercurial would trust an uploaded hgrc (hooks, extensions) on the server, and nothing here needs one. + if (info is DirectoryInfo hg) + foreach (var hgrc in hg.EnumerateFiles("hgrc")) hgrc.Delete(); + continue; + } if (info is DirectoryInfo dir) dir.Delete(true); else info.Delete(); } @@ -323,7 +329,7 @@ public Task RevertRepo(ProjectCode code, string revHash) // 1. Rename repo to repo-backup-date (verifying first that it does not exist, adding -NNN at the end (001, 002, 003) if it does) // 2. Make empty directory (NOT a repo yet) with this project code // 3. Clone repo-backup-date-NNN into empty directory, passing "-r revHash" param - // 4. Copy .hg/hgrc from backup dir, overwriting the one in the cloned dir + // 4. Delete the .hg/hgrc that the clone writes (it only points back at the backup); server repos don't keep one // // Will need an SSH key as a k8s secret, put it into authorized_keys on the hgweb side so that lexbox can do "ssh hgweb hg clone ..." } diff --git a/backend/Testing/LexCore/Services/HgServiceTests.cs b/backend/Testing/LexCore/Services/HgServiceTests.cs index 1e0b43e191..9b50218a6f 100644 --- a/backend/Testing/LexCore/Services/HgServiceTests.cs +++ b/backend/Testing/LexCore/Services/HgServiceTests.cs @@ -109,6 +109,29 @@ public async Task CanFinishResetByUnZippingAnArchive(string filePath) .Should().ContainSingle().Which.Should().Be(Path.Join(".hg", "important-file.bin")); } + [Theory] + [InlineData("")] + [InlineData("unzip-test/")] + public async Task FinishResetDropsUploadedHgrc(string prefix) + { + var code = "unzip-test-hgrc"; + await _hgService.InitRepo(code); + + using var stream = new MemoryStream(); + using (var zipArchive = new ZipArchive(stream, ZipArchiveMode.Create, true)) + { + CreateSimpleEntry(zipArchive, prefix + ".hg/hgrc"); + CreateSimpleEntry(zipArchive, prefix + ".hg/important-file.bin"); + } + stream.Position = 0; + await _hgService.FinishReset(code, stream); + + var repoPath = Path.GetFullPath(Path.Join(_hgConfig.RepoPath, "u", code)); + Directory.EnumerateFiles(repoPath, "*", SearchOption.AllDirectories) + .Select(p => Path.GetRelativePath(repoPath, p)) + .Should().ContainSingle().Which.Should().Be(Path.Join(".hg", "important-file.bin")); + } + [Theory] [InlineData("-xy")] [InlineData("-x-y-z")]