diff --git a/src/main/java/git/lfs/migrate/GitConverter.java b/src/main/java/git/lfs/migrate/GitConverter.java index e279a1e..3c21cce 100644 --- a/src/main/java/git/lfs/migrate/GitConverter.java +++ b/src/main/java/git/lfs/migrate/GitConverter.java @@ -73,7 +73,7 @@ public ConvertTask convertTask(@NotNull ObjectReader reader, @NotNull TaskKey ke return convertCommitTask((RevCommit) revObject); } if (revObject instanceof RevTree) { - return convertTreeTask(reader, revObject, false); + return convertTreeTask(reader, revObject, Objects.requireNonNull(key.getPath())); } if (revObject instanceof RevBlob) { return copyTask(reader, revObject); @@ -83,13 +83,6 @@ public ConvertTask convertTask(@NotNull ObjectReader reader, @NotNull TaskKey ke } throw new IllegalStateException("Unsupported object type: " + key + " (" + revObject.getClass().getName() + ")"); } - case Root: { - final RevObject revObject = new RevWalk(reader).parseAny(key.getObjectId()); - if (revObject instanceof RevTree) { - return convertTreeTask(reader, revObject, true); - } - throw new IllegalStateException("Unsupported object type: " + key + " (" + revObject.getClass().getName() + ")"); - } case Attribute: return createAttributesTask(reader, key.getObjectId()); case UploadLfs: @@ -122,14 +115,14 @@ private ConvertTask convertTagTask(@NotNull RevTag revObject) throws IOException @Override public Iterable depends() { return Collections.singletonList( - new TaskKey(TaskType.Simple, revObject.getObject()) + new TaskKey(TaskType.Simple, "", revObject.getObject()) ); } @NotNull @Override public ObjectId convert(@NotNull ObjectInserter inserter, @NotNull ConvertResolver resolver, @Nullable Uploader uploader) throws IOException { - final ObjectId id = resolver.resolve(TaskType.Simple, revObject.getObject()); + final ObjectId id = resolver.resolve(TaskType.Simple, "", revObject.getObject()); final TagBuilder builder = new TagBuilder(); builder.setMessage(revObject.getFullMessage()); builder.setTag(revObject.getTagName()); @@ -148,9 +141,9 @@ private ConvertTask convertCommitTask(@NotNull RevCommit revObject) throws IOExc public Iterable depends() { List result = new ArrayList<>(); for (RevCommit parent : revObject.getParents()) { - result.add(new TaskKey(TaskType.Simple, parent)); + result.add(new TaskKey(TaskType.Simple, "", parent)); } - result.add(new TaskKey(TaskType.Root, revObject.getTree())); + result.add(new TaskKey(TaskType.Simple, "", revObject.getTree())); return result; } @@ -164,39 +157,43 @@ public ObjectId convert(@NotNull ObjectInserter inserter, @NotNull ConvertResolv builder.setMessage(revObject.getFullMessage()); // Set parents for (RevCommit oldParent : revObject.getParents()) { - builder.addParentId(resolver.resolve(TaskType.Simple, oldParent)); + builder.addParentId(resolver.resolve(TaskType.Simple, "", oldParent)); } // Set tree - builder.setTreeId(resolver.resolve(TaskType.Root, revObject.getTree())); + builder.setTreeId(resolver.resolve(TaskType.Simple, "", revObject.getTree())); return inserter.insert(builder); } }; } @NotNull - private ConvertTask convertTreeTask(@NotNull ObjectReader reader, @NotNull ObjectId id, boolean rootTree) { + private ConvertTask convertTreeTask(@NotNull ObjectReader reader, @NotNull ObjectId id, @NotNull String path) { return new ConvertTask() { @NotNull private List getEntries() throws IOException { final List entries = new ArrayList<>(); final CanonicalTreeParser treeParser = new CanonicalTreeParser(null, reader, id); - boolean needAttributes = rootTree; + boolean needAttributes = path.isEmpty(); while (!treeParser.eof()) { final FileMode fileMode = treeParser.getEntryFileMode(); final TaskType blobTask; + final String pathTask; if (needAttributes && treeParser.getEntryPathString().equals(GIT_ATTRIBUTES)) { blobTask = TaskType.Attribute; + pathTask = null; needAttributes = false; } else if (isFile(fileMode) && matchFilename(treeParser.getEntryPathString())) { blobTask = TaskType.UploadLfs; + pathTask = null; } else { blobTask = TaskType.Simple; + pathTask = path + "/" + treeParser.getEntryPathString(); } - entries.add(new GitTreeEntry(fileMode, new TaskKey(blobTask, treeParser.getEntryObjectId()), treeParser.getEntryPathString())); + entries.add(new GitTreeEntry(fileMode, new TaskKey(blobTask, pathTask, treeParser.getEntryObjectId()), treeParser.getEntryPathString())); treeParser.next(); } if (needAttributes && suffixes.length > 0) { - entries.add(new GitTreeEntry(FileMode.REGULAR_FILE, new TaskKey(TaskType.Attribute, ObjectId.zeroId()), GIT_ATTRIBUTES)); + entries.add(new GitTreeEntry(FileMode.REGULAR_FILE, new TaskKey(TaskType.Attribute, null, ObjectId.zeroId()), GIT_ATTRIBUTES)); } return entries; } @@ -410,7 +407,19 @@ private InputStream openAttributes(@NotNull ObjectReader reader, @Nullable Objec } public enum TaskType { - Simple, Root, Attribute, UploadLfs, + Simple(true), + Attribute(false), + UploadLfs(false); + + TaskType(boolean needPath) { + this.needPath = needPath; + } + + private final boolean needPath; + + public boolean needPath() { + return needPath; + } } public interface ConvertResolver { @@ -418,8 +427,8 @@ public interface ConvertResolver { ObjectId resolve(@NotNull TaskKey key); @NotNull - default ObjectId resolve(@NotNull TaskType type, @NotNull ObjectId objectId) { - return resolve(new TaskKey(type, objectId)); + default ObjectId resolve(@NotNull TaskType type, @Nullable String path, @NotNull ObjectId objectId) { + return resolve(new TaskKey(type, path, objectId)); } } diff --git a/src/main/java/git/lfs/migrate/Main.java b/src/main/java/git/lfs/migrate/Main.java index 8a4a627..72c07c9 100644 --- a/src/main/java/git/lfs/migrate/Main.java +++ b/src/main/java/git/lfs/migrate/Main.java @@ -150,7 +150,7 @@ public static void processRepository(@NotNull File srcPath, @NotNull File dstPat for (Map.Entry ref : srcRepo.getAllRefs().entrySet()) { RefUpdate refUpdate = dstRepo.updateRef(ref.getKey()); final ObjectId oldId = ref.getValue().getObjectId(); - final ObjectId newId = converted.get(new TaskKey(GitConverter.TaskType.Simple, oldId)); + final ObjectId newId = converted.get(new TaskKey(GitConverter.TaskType.Simple, "", oldId)); refUpdate.setNewObjectId(newId); refUpdate.update(); log.info(" convert ref: {} -> {} ({})", oldId.getName(), newId.getName(), ref.getKey()); @@ -269,7 +269,7 @@ private static SimpleDirectedGraph loadTaskGraph(@NotNull final Deque queue = new ArrayDeque<>(); // Heads for (Ref ref : refs.values()) { - final TaskKey taskKey = new TaskKey(GitConverter.TaskType.Simple, ref.getObjectId()); + final TaskKey taskKey = new TaskKey(GitConverter.TaskType.Simple, "", ref.getObjectId()); if (graph.addVertex(taskKey)) { queue.add(taskKey); reporter.increment(); diff --git a/src/main/java/git/lfs/migrate/TaskKey.java b/src/main/java/git/lfs/migrate/TaskKey.java index 15bba5d..ba2da6b 100644 --- a/src/main/java/git/lfs/migrate/TaskKey.java +++ b/src/main/java/git/lfs/migrate/TaskKey.java @@ -2,6 +2,9 @@ import org.eclipse.jgit.lib.ObjectId; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; /** * Key of converter task. @@ -14,10 +17,16 @@ public final class TaskKey { private final GitConverter.TaskType type; @NotNull private final ObjectId objectId; + @Nullable + private final String path; - public TaskKey(@NotNull GitConverter.TaskType type, @NotNull ObjectId objectId) { + public TaskKey(@NotNull GitConverter.TaskType type, @Nullable String path, @NotNull ObjectId objectId) { this.type = type; + this.path = path; this.objectId = objectId.copy(); + if (type.needPath() == (path == null)) { + throw new IllegalStateException(); + } } @NotNull @@ -30,6 +39,11 @@ public ObjectId getObjectId() { return objectId; } + @Nullable + public String getPath() { + return path; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -38,19 +52,22 @@ public boolean equals(Object o) { TaskKey taskKey = (TaskKey) o; return (type == taskKey.type) - && objectId.equals(taskKey.objectId); - + && objectId.equals(taskKey.objectId) + && Objects.equals(path, taskKey.path); } @Override public int hashCode() { int result = type.hashCode(); result = 31 * result + objectId.hashCode(); + if (path != null) { + result = 31 * result + path.hashCode(); + } return result; } @Override public String toString() { - return type + ":" + objectId.name(); + return type + ":" + objectId.name() + (path == null ? "" : " (" + path + ")"); } }