From 7186b36f2d69c756e9ae8fdde9eb07d2ad53d8f7 Mon Sep 17 00:00:00 2001 From: Robin Stocker Date: Tue, 19 Jul 2016 14:12:34 +0200 Subject: [PATCH] Fix object size being 0 when retrying request (#14) Because the code only put the hash in the cache and not the size, the size that was sent in a retried request was 0. Some server implementations check the size, so those requests may fail. To fix it, also put the size in the cache and use it when creating a request from the cache. --- .../java/git/lfs/migrate/GitConverter.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/git/lfs/migrate/GitConverter.java b/src/main/java/git/lfs/migrate/GitConverter.java index 917f1ba..53a5b15 100644 --- a/src/main/java/git/lfs/migrate/GitConverter.java +++ b/src/main/java/git/lfs/migrate/GitConverter.java @@ -41,7 +41,7 @@ public class GitConverter implements AutoCloseable { @NotNull private final DB cache; @NotNull - private final HTreeMap cacheSha256; + private final HTreeMap cacheMeta; public GitConverter(@NotNull File cachePath, @NotNull File basePath, @NotNull String[] globs) throws IOException, InvalidPatternException { this.basePath = basePath; @@ -60,7 +60,7 @@ public GitConverter(@NotNull File cachePath, @NotNull File basePath, @NotNull St .mmapFileEnable() .cacheSoftRefEnable() .make(); - cacheSha256 = cache.getHashMap("sha256"); + cacheMeta = cache.getHashMap("meta"); } @Override @@ -283,7 +283,7 @@ public ObjectId convert(@NotNull ObjectInserter inserter, @NotNull ConvertResolv private String createRemoteFile(@NotNull ObjectId id, @NotNull ObjectLoader loader, @NotNull Uploader uploader) throws IOException { // Create LFS stream. final String hash; - final String cached = cacheSha256.get(id.name()); + final MetaData cached = cacheMeta.get(id.name()); long size = 0; if (cached == null) { final MessageDigest md = createSha256(); @@ -297,10 +297,11 @@ private String createRemoteFile(@NotNull ObjectId id, @NotNull ObjectLoader load } } hash = new String(Hex.encodeHex(md.digest(), true)); - cacheSha256.put(id.name(), hash); + cacheMeta.put(id.name(), new MetaData(hash, size)); cache.commit(); } else { - hash = cached; + hash = cached.oid; + size = cached.size; } uploader.upload(id, new Meta(hash, size)); return hash; @@ -311,18 +312,20 @@ private String createLocalFile(@NotNull ObjectId id, @NotNull ObjectLoader loade // Create LFS stream. final File tmpFile = new File(tempPath, UUID.randomUUID().toString()); final MessageDigest md = createSha256(); + int size = 0; try (InputStream istream = loader.openStream(); OutputStream ostream = new FileOutputStream(tmpFile)) { byte[] buffer = new byte[0x10000]; while (true) { - int size = istream.read(buffer); - if (size <= 0) break; - ostream.write(buffer, 0, size); - md.update(buffer, 0, size); + int read = istream.read(buffer); + if (read <= 0) break; + ostream.write(buffer, 0, read); + md.update(buffer, 0, read); + size += read; } } final String hash = new String(Hex.encodeHex(md.digest(), true)); - cacheSha256.putIfAbsent(id.name(), hash); + cacheMeta.putIfAbsent(id.name(), new MetaData(hash, size)); cache.commit(); // Rename file. final File lfsFile = new File(basePath, "lfs/objects/" + hash.substring(0, 2) + "/" + hash.substring(2, 4) + "/" + hash); @@ -460,4 +463,14 @@ public interface ConvertTask { public interface Uploader { void upload(@NotNull ObjectId oid, @NotNull Meta meta); } + + private static class MetaData implements Serializable { + private final String oid; + private final long size; + + MetaData(String oid, long size) { + this.oid = oid; + this.size = size; + } + } }