From 72f19cf96ffc9317fd96a965a1d37095ceaf6b87 Mon Sep 17 00:00:00 2001 From: David Ostrovsky Date: Tue, 20 Jan 2015 22:51:40 +0100 Subject: [PATCH] InlineEdit: Add method for renaming files in change edit Change-Id: I9d538bd58d16b0560ee33c4ae7c7ddd8f45ca9c7 --- .../gerrit/acceptance/edit/ChangeEditIT.java | 18 +++++ .../server/edit/ChangeEditModifier.java | 69 ++++++++++++++----- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java index 25b3aceae3..a1168a8fad 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/edit/ChangeEditIT.java @@ -79,6 +79,7 @@ public class ChangeEditIT extends AbstractDaemonTest { private final static String FILE_NAME = "foo"; private final static String FILE_NAME2 = "foo2"; + private final static String FILE_NAME3 = "foo3"; private final static byte[] CONTENT_OLD = "bar".getBytes(UTF_8); private final static byte[] CONTENT_NEW = "baz".getBytes(UTF_8); private final static byte[] CONTENT_NEW2 = "qux".getBytes(UTF_8); @@ -371,6 +372,23 @@ public class ChangeEditIT extends AbstractDaemonTest { } } + @Test + public void renameExistingFile() throws Exception { + assertThat(modifier.createEdit(change, ps)).isEqualTo(RefUpdate.Result.NEW); + Optional edit = editUtil.byChange(change); + assertThat(modifier.renameFile(edit.get(), FILE_NAME, FILE_NAME3)) + .isEqualTo(RefUpdate.Result.FORCED); + edit = editUtil.byChange(change); + assertByteArray(fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()), + ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME3), CONTENT_OLD); + try { + fileUtil.getContent(projectCache.get(edit.get().getChange().getProject()), + ObjectId.fromString(edit.get().getRevision().get()), FILE_NAME); + fail("ResourceNotFoundException expected"); + } catch (ResourceNotFoundException rnfe) { + } + } + @Test public void createEditByDeletingExistingFileRest() throws Exception { RestResponse r = adminSession.delete(urlEditFile()); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java b/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java index 986a442777..71c54fe076 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/edit/ChangeEditModifier.java @@ -81,6 +81,7 @@ public class ChangeEditModifier { private static enum TreeOperation { CHANGE_ENTRY, DELETE_ENTRY, + RENAME_ENTRY, RESTORE_ENTRY } private final TimeZone tz; @@ -271,7 +272,7 @@ public class ChangeEditModifier { public RefUpdate.Result modifyFile(ChangeEdit edit, String file, RawInput content) throws AuthException, InvalidChangeOperationException, IOException { - return modify(TreeOperation.CHANGE_ENTRY, edit, file, content); + return modify(TreeOperation.CHANGE_ENTRY, edit, file, null, content); } /** @@ -287,7 +288,24 @@ public class ChangeEditModifier { public RefUpdate.Result deleteFile(ChangeEdit edit, String file) throws AuthException, InvalidChangeOperationException, IOException { - return modify(TreeOperation.DELETE_ENTRY, edit, file, null); + return modify(TreeOperation.DELETE_ENTRY, edit, file, null, null); + } + + /** + * Rename file in existing change edit. + * + * @param edit change edit + * @param file path to rename + * @param newFile path to rename the file to + * @return result + * @throws AuthException + * @throws InvalidChangeOperationException + * @throws IOException + */ + public RefUpdate.Result renameFile(ChangeEdit edit, String file, + String newFile) throws AuthException, InvalidChangeOperationException, + IOException { + return modify(TreeOperation.RENAME_ENTRY, edit, file, newFile, null); } /** @@ -303,11 +321,11 @@ public class ChangeEditModifier { public RefUpdate.Result restoreFile(ChangeEdit edit, String file) throws AuthException, InvalidChangeOperationException, IOException { - return modify(TreeOperation.RESTORE_ENTRY, edit, file, null); + return modify(TreeOperation.RESTORE_ENTRY, edit, file, null, null); } - private RefUpdate.Result modify(TreeOperation op, - ChangeEdit edit, String file, @Nullable RawInput content) + private RefUpdate.Result modify(TreeOperation op, ChangeEdit edit, + String file, @Nullable String newFile, @Nullable RawInput content) throws AuthException, IOException, InvalidChangeOperationException { if (!currentUser.get().isIdentifiedUser()) { throw new AuthException("Authentication required"); @@ -327,6 +345,7 @@ public class ChangeEditModifier { prevEdit, reader, file, + newFile, toBlob(inserter, content)); if (ObjectId.equals(newTree, prevEdit.getTree())) { throw new InvalidChangeOperationException("no changes were made"); @@ -396,8 +415,8 @@ public class ChangeEditModifier { private static ObjectId writeNewTree(TreeOperation op, RevWalk rw, ObjectInserter ins, RevCommit prevEdit, ObjectReader reader, - String fileName, final @Nullable ObjectId content) - throws IOException { + String fileName, @Nullable String newFile, + final @Nullable ObjectId content) throws IOException { DirCache newTree = readTree(reader, prevEdit); DirCacheEditor dce = newTree.editor(); switch (op) { @@ -405,6 +424,16 @@ public class ChangeEditModifier { dce.add(new DeletePath(fileName)); break; + case RENAME_ENTRY: + rw.parseHeaders(prevEdit); + TreeWalk tw = + TreeWalk.forPath(rw.getObjectReader(), fileName, prevEdit.getTree()); + if (tw != null) { + dce.add(new DeletePath(fileName)); + addFileToCommit(newFile, dce, tw); + } + break; + case CHANGE_ENTRY: checkNotNull(content, "new content required"); dce.add(new PathEdit(fileName) { @@ -426,28 +455,32 @@ public class ChangeEditModifier { RevCommit base = prevEdit.getParent(0); rw.parseHeaders(base); - TreeWalk tw = - TreeWalk.forPath(rw.getObjectReader(), fileName, base.getTree()); + tw = TreeWalk.forPath(rw.getObjectReader(), fileName, base.getTree()); if (tw == null) { dce.add(new DeletePath(fileName)); break; } - final FileMode mode = tw.getFileMode(0); - final ObjectId oid = tw.getObjectId(0); - dce.add(new PathEdit(fileName) { - @Override - public void apply(DirCacheEntry ent) { - ent.setFileMode(mode); - ent.setObjectId(oid); - } - }); + addFileToCommit(fileName, dce, tw); break; } dce.finish(); return newTree.writeTree(ins); } + private static void addFileToCommit(String newFile, DirCacheEditor dce, + TreeWalk tw) { + final FileMode mode = tw.getFileMode(0); + final ObjectId oid = tw.getObjectId(0); + dce.add(new PathEdit(newFile) { + @Override + public void apply(DirCacheEntry ent) { + ent.setFileMode(mode); + ent.setObjectId(oid); + } + }); + } + private static DirCache readTree(ObjectReader reader, RevCommit prevEdit) throws IOException { DirCache dc = DirCache.newInCore();