InlineEdit: Add method for renaming files in change edit

Change-Id: I9d538bd58d16b0560ee33c4ae7c7ddd8f45ca9c7
This commit is contained in:
David Ostrovsky
2015-01-20 22:51:40 +01:00
committed by David Pursehouse
parent d148d9f2ba
commit 72f19cf96f
2 changed files with 69 additions and 18 deletions

View File

@@ -79,6 +79,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
private final static String FILE_NAME = "foo"; private final static String FILE_NAME = "foo";
private final static String FILE_NAME2 = "foo2"; 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_OLD = "bar".getBytes(UTF_8);
private final static byte[] CONTENT_NEW = "baz".getBytes(UTF_8); private final static byte[] CONTENT_NEW = "baz".getBytes(UTF_8);
private final static byte[] CONTENT_NEW2 = "qux".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<ChangeEdit> 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 @Test
public void createEditByDeletingExistingFileRest() throws Exception { public void createEditByDeletingExistingFileRest() throws Exception {
RestResponse r = adminSession.delete(urlEditFile()); RestResponse r = adminSession.delete(urlEditFile());

View File

@@ -81,6 +81,7 @@ public class ChangeEditModifier {
private static enum TreeOperation { private static enum TreeOperation {
CHANGE_ENTRY, CHANGE_ENTRY,
DELETE_ENTRY, DELETE_ENTRY,
RENAME_ENTRY,
RESTORE_ENTRY RESTORE_ENTRY
} }
private final TimeZone tz; private final TimeZone tz;
@@ -271,7 +272,7 @@ public class ChangeEditModifier {
public RefUpdate.Result modifyFile(ChangeEdit edit, public RefUpdate.Result modifyFile(ChangeEdit edit,
String file, RawInput content) throws AuthException, String file, RawInput content) throws AuthException,
InvalidChangeOperationException, IOException { 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, public RefUpdate.Result deleteFile(ChangeEdit edit,
String file) throws AuthException, InvalidChangeOperationException, String file) throws AuthException, InvalidChangeOperationException,
IOException { 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, public RefUpdate.Result restoreFile(ChangeEdit edit,
String file) throws AuthException, InvalidChangeOperationException, String file) throws AuthException, InvalidChangeOperationException,
IOException { IOException {
return modify(TreeOperation.RESTORE_ENTRY, edit, file, null); return modify(TreeOperation.RESTORE_ENTRY, edit, file, null, null);
} }
private RefUpdate.Result modify(TreeOperation op, private RefUpdate.Result modify(TreeOperation op, ChangeEdit edit,
ChangeEdit edit, String file, @Nullable RawInput content) String file, @Nullable String newFile, @Nullable RawInput content)
throws AuthException, IOException, InvalidChangeOperationException { throws AuthException, IOException, InvalidChangeOperationException {
if (!currentUser.get().isIdentifiedUser()) { if (!currentUser.get().isIdentifiedUser()) {
throw new AuthException("Authentication required"); throw new AuthException("Authentication required");
@@ -327,6 +345,7 @@ public class ChangeEditModifier {
prevEdit, prevEdit,
reader, reader,
file, file,
newFile,
toBlob(inserter, content)); toBlob(inserter, content));
if (ObjectId.equals(newTree, prevEdit.getTree())) { if (ObjectId.equals(newTree, prevEdit.getTree())) {
throw new InvalidChangeOperationException("no changes were made"); throw new InvalidChangeOperationException("no changes were made");
@@ -396,8 +415,8 @@ public class ChangeEditModifier {
private static ObjectId writeNewTree(TreeOperation op, RevWalk rw, private static ObjectId writeNewTree(TreeOperation op, RevWalk rw,
ObjectInserter ins, RevCommit prevEdit, ObjectReader reader, ObjectInserter ins, RevCommit prevEdit, ObjectReader reader,
String fileName, final @Nullable ObjectId content) String fileName, @Nullable String newFile,
throws IOException { final @Nullable ObjectId content) throws IOException {
DirCache newTree = readTree(reader, prevEdit); DirCache newTree = readTree(reader, prevEdit);
DirCacheEditor dce = newTree.editor(); DirCacheEditor dce = newTree.editor();
switch (op) { switch (op) {
@@ -405,6 +424,16 @@ public class ChangeEditModifier {
dce.add(new DeletePath(fileName)); dce.add(new DeletePath(fileName));
break; 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: case CHANGE_ENTRY:
checkNotNull(content, "new content required"); checkNotNull(content, "new content required");
dce.add(new PathEdit(fileName) { dce.add(new PathEdit(fileName) {
@@ -426,26 +455,30 @@ public class ChangeEditModifier {
RevCommit base = prevEdit.getParent(0); RevCommit base = prevEdit.getParent(0);
rw.parseHeaders(base); rw.parseHeaders(base);
TreeWalk tw = tw = TreeWalk.forPath(rw.getObjectReader(), fileName, base.getTree());
TreeWalk.forPath(rw.getObjectReader(), fileName, base.getTree());
if (tw == null) { if (tw == null) {
dce.add(new DeletePath(fileName)); dce.add(new DeletePath(fileName));
break; break;
} }
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 FileMode mode = tw.getFileMode(0);
final ObjectId oid = tw.getObjectId(0); final ObjectId oid = tw.getObjectId(0);
dce.add(new PathEdit(fileName) { dce.add(new PathEdit(newFile) {
@Override @Override
public void apply(DirCacheEntry ent) { public void apply(DirCacheEntry ent) {
ent.setFileMode(mode); ent.setFileMode(mode);
ent.setObjectId(oid); ent.setObjectId(oid);
} }
}); });
break;
}
dce.finish();
return newTree.writeTree(ins);
} }
private static DirCache readTree(ObjectReader reader, RevCommit prevEdit) private static DirCache readTree(ObjectReader reader, RevCommit prevEdit)