Fix hg import/export issues

This commit is contained in:
Rene Pfeuffer
2025-07-07 15:13:50 +02:00
parent d8406cbe8b
commit 605d77e383
4 changed files with 30 additions and 3 deletions

View File

@@ -0,0 +1,2 @@
- type: fixed
description: Various issues for repository dump export and import without metadata

View File

@@ -148,6 +148,8 @@ public final class Archives {
String filePath = path + "/" + fileOrDir.getFileName().toString(); String filePath = path + "/" + fileOrDir.getFileName().toString();
if (Files.isDirectory(fileOrDir)) { if (Files.isDirectory(fileOrDir)) {
createTarEntryForFiles(filePath, fileOrDir, taos); createTarEntryForFiles(filePath, fileOrDir, taos);
} else if (Files.isSymbolicLink(fileOrDir)) {
createArchiveEntryForLink(filePath, fileOrDir, taos);
} else { } else {
createArchiveEntryForFile(filePath, fileOrDir, taos); createArchiveEntryForFile(filePath, fileOrDir, taos);
} }
@@ -159,6 +161,14 @@ public final class Archives {
} }
} }
private static void createArchiveEntryForLink(String filePath, Path path, TarArchiveOutputStream taos) throws IOException {
String linkTarget = Files.readSymbolicLink(path).toString();
TarArchiveEntry entry = new TarArchiveEntry(filePath, TarArchiveEntry.LF_SYMLINK);
entry.setLinkName(linkTarget);
taos.putArchiveEntry(entry);
taos.closeArchiveEntry();
}
private void createArchiveEntryForFile(String filePath, Path path, TarArchiveOutputStream taos) throws IOException { private void createArchiveEntryForFile(String filePath, Path path, TarArchiveOutputStream taos) throws IOException {
TarArchiveEntry entry = new TarArchiveEntry(filePath); TarArchiveEntry entry = new TarArchiveEntry(filePath);
entry.setSize(path.toFile().length()); entry.setSize(path.toFile().length());
@@ -189,10 +199,20 @@ public final class Archives {
while ((entry = tais.getNextTarEntry()) != null) { while ((entry = tais.getNextTarEntry()) != null) {
Path filePath = targetPath.resolve(entry.getName()); Path filePath = targetPath.resolve(entry.getName());
createDirectoriesIfNestedFile(filePath); createDirectoriesIfNestedFile(filePath);
if (entry.isDirectory()) {
Files.createDirectories(filePath);
} else if (entry.isSymbolicLink() || entry.isLink()) {
String linkTarget = entry.getLinkName();
if (linkTarget == null || linkTarget.isEmpty()) {
throw new ArchiveException("Symbolic link entry '" + entry.getName() + "' has no target", null);
}
Files.createSymbolicLink(filePath, Path.of(linkTarget));
} else {
Files.copy(tais, filePath, StandardCopyOption.REPLACE_EXISTING); Files.copy(tais, filePath, StandardCopyOption.REPLACE_EXISTING);
} }
} }
} }
}
private void createDirectoriesIfNestedFile(Path filePath) throws IOException { private void createDirectoriesIfNestedFile(Path filePath) throws IOException {
Path directory = filePath.getParent(); Path directory = filePath.getParent();

View File

@@ -23,6 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import sonia.scm.repository.RepositoryHookEvent; import sonia.scm.repository.RepositoryHookEvent;
import sonia.scm.repository.api.UnbundleResponse; import sonia.scm.repository.api.UnbundleResponse;
import sonia.scm.util.IOUtil;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@@ -57,6 +58,10 @@ public class HgUnbundleCommand implements UnbundleCommand {
if (!Files.exists(repositoryDir)) { if (!Files.exists(repositoryDir)) {
Files.createDirectories(repositoryDir); Files.createDirectories(repositoryDir);
} }
Path hgDir = repositoryDir.resolve(".hg");
if (Files.exists(hgDir)) {
IOUtil.delete(hgDir.toFile());
}
unbundleRepositoryFromRequest(request, repositoryDir); unbundleRepositoryFromRequest(request, repositoryDir);
fireHookEvent(request); fireHookEvent(request);

View File

@@ -474,7 +474,7 @@ public class RepositoryExportResource {
}; };
return createResponse(repository, fileExtension, compressed, output); return createResponse(repository, fileExtension, compressed, output);
} }
} catch (IOException e) { } catch (Exception e) {
notificationHandler.handleFailedExport(repository); notificationHandler.handleFailedExport(repository);
throw new ExportFailedException(entity(repository).build(), "repository export failed", e); throw new ExportFailedException(entity(repository).build(), "repository export failed", e);
} }