Fix edge cases in move (#1874)

Fixes edge cases for "move" in the modify command, like

- reject backslashes in validation
- add overwrite option
- check for invalid source and target options

This is an update to the implementation of "move" in #1859.

Co-authored-by: Matthias Thieroff <matthias.thieroff@cloudogu.com>
This commit is contained in:
René Pfeuffer
2021-11-30 08:49:47 +01:00
committed by GitHub
parent 5eb1d9cd22
commit 6ea77b42ca
19 changed files with 400 additions and 242 deletions

View File

@@ -29,6 +29,7 @@ import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.attributes.FilterCommandRegistry;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.revwalk.RevCommit;
import sonia.scm.ConcurrentModificationException;
import sonia.scm.ContextEntry;
@@ -173,13 +174,21 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman
}
private void addFileToGit(String toBeCreated) throws GitAPIException {
getClone().add().addFilepattern(removeStartingPathSeparators(toBeCreated)).call();
String toBeCreatedWithoutLeadingSlash = removeStartingPathSeparators(toBeCreated);
DirCache addResult = getClone().add().addFilepattern(toBeCreatedWithoutLeadingSlash).call();
if (addResult.findEntry(toBeCreatedWithoutLeadingSlash) < 0) {
throw new ModificationFailedException(ContextEntry.ContextBuilder.entity("File", toBeCreated).in(repository).build(), "Could not add file to repository");
}
}
@Override
public void doScmDelete(String toBeDeleted) {
try {
getClone().rm().addFilepattern(removeStartingPathSeparators(toBeDeleted)).call();
String toBeDeletedWithoutLeadingSlash = removeStartingPathSeparators(toBeDeleted);
DirCache deleteResult = getClone().rm().addFilepattern(toBeDeletedWithoutLeadingSlash).call();
if (deleteResult.findEntry(toBeDeletedWithoutLeadingSlash) >= 0) {
throw new ModificationFailedException(ContextEntry.ContextBuilder.entity("File", toBeDeleted).in(repository).build(), "Could not delete file from repository");
}
} catch (GitAPIException e) {
throwInternalRepositoryException("could not remove file from index", e);
}
@@ -206,8 +215,8 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman
}
private String removeStartingPathSeparators(String path) {
while (path.startsWith(File.separator)) {
path = path.substring(1);
if (path.startsWith("/")) {
return path.substring(1);
}
return path;
}

View File

@@ -66,16 +66,14 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("new_file", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
String newRef = command.execute(request);
try (Git git = new Git(createContext().open())) {
RevCommit lastCommit = getLastCommit(git);
assertThat(lastCommit.getFullMessage()).isEqualTo("test commit");
assertThat(lastCommit.getFullMessage()).isEqualTo("Make some change");
assertThat(lastCommit.getAuthorIdent().getName()).isEqualTo("Dirk Gently");
assertThat(newRef).isEqualTo(lastCommit.toObjectId().name());
}
@@ -87,11 +85,9 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.setBranch("test-branch");
request.addRequest(new ModifyCommandRequest.CreateFileRequest("new_file", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
String newRef = command.execute(request);
@@ -108,10 +104,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("new_file", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -126,10 +120,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("/new_file", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -144,10 +136,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("a.txt", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -158,10 +148,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("a.txt/newFile", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -172,10 +160,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("a.txt", newFile, true));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -190,10 +176,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.ModifyFileRequest("a.txt", newFile));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -208,10 +192,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.ModifyFileRequest("no.such.file", newFile));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -222,10 +204,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("b.txt", newFile, true));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -236,10 +216,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("irrelevant", newFile, true));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
request.setExpectedRevision("abc");
command.execute(request);
@@ -249,10 +227,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldDeleteExistingFile() throws IOException, GitAPIException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.DeleteFileRequest("a.txt", false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -265,10 +241,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldDeleteExistingDirectory() throws IOException, GitAPIException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.DeleteFileRequest("c", true));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -293,10 +267,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldThrowNotFoundExceptionWhenFileToDeleteDoesNotExist() {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.DeleteFileRequest("no/such/file", false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -305,11 +277,9 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldThrowNotFoundExceptionWhenBranchDoesNotExist() {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
ModifyCommandRequest request = prepareModifyCommandRequest();
request.setBranch("does-not-exist");
request.setCommitMessage("test commit");
request.addRequest(new ModifyCommandRequest.DeleteFileRequest("a.txt", false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -320,11 +290,9 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.setBranch("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4");
request.addRequest(new ModifyCommandRequest.CreateFileRequest("irrelevant", newFile, true));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -335,10 +303,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("new_file", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -356,11 +322,9 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.setSign(false);
request.addRequest(new ModifyCommandRequest.CreateFileRequest("new_file", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -377,10 +341,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest("new_file", newFile, false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
@@ -398,10 +360,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("test commit");
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.CreateFileRequest(".git/ome.txt", newFile, true));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);
}
@@ -410,10 +370,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldThrowErrorIfRelativePathIsOutsideOfWorkdir() {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("please rename this file");
request.setAuthor(new Person("Peter Pan", "peter@pan.net"));
request.addRequest(new ModifyCommandRequest.MoveRequest("g/h/c", "/../../../../b"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("g/h/c", "/../../../../b", false));
command.execute(request);
}
@@ -422,10 +380,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldRenameFile() throws GitAPIException, IOException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("please rename this file");
request.setAuthor(new Person("Peter Pan", "peter@pan.net"));
request.addRequest(new ModifyCommandRequest.MoveRequest("b.txt", "/d.txt"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("b.txt", "/d.txt", false));
command.execute(request);
@@ -441,10 +397,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldThrowAlreadyExistsException() {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c"));
request.setCommitMessage("please rename my file pretty please");
request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c", false));
command.execute(request);
}
@@ -453,10 +407,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldRenameFolder() throws GitAPIException, IOException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("please move this folder");
request.setAuthor(new Person("Peter Pan", "peter@pan.net"));
request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/notc"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/notc", false));
command.execute(request);
@@ -474,10 +426,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldMoveFileToExistingFolder() throws GitAPIException, IOException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("please move this file");
request.setAuthor(new Person("Peter Pan", "peter@pan.net"));
request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c/z.txt"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c/z.txt", false));
command.execute(request);
@@ -495,10 +445,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldMoveFolderToExistingFolder() throws GitAPIException, IOException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("please rename this file");
request.setAuthor(new Person("Peter Pan", "peter@pan.net"));
request.addRequest(new ModifyCommandRequest.MoveRequest("g/h", "/g/k/h"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("g/h", "/g/k/h", false));
command.execute(request);
@@ -514,10 +462,8 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
public void shouldMoveFileToNonExistentFolder() throws GitAPIException, IOException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("please move this file");
request.setAuthor(new Person("Peter Pan", "peter@pan.net"));
request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/y/z.txt"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/y/z.txt", false));
command.execute(request);
@@ -529,14 +475,29 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
assertInTree(assertions);
}
@Test
public void shouldMoveFileWithOverwrite() throws GitAPIException, IOException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/b.txt", true));
command.execute(request);
TreeAssertions assertions = fileFinder -> {
assertThat(fileFinder.findFile("a.txt")).isFalse();
assertThat(fileFinder.findFile("b.txt")).isTrue();
};
assertInTree(assertions);
}
@Test
public void shouldMoveFolderToNonExistentFolder() throws GitAPIException, IOException {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("please move this file");
request.setAuthor(new Person("Peter Pan", "peter@pan.net"));
request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/j/k/c"));
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/j/k/c", false));
command.execute(request);
@@ -549,4 +510,22 @@ public class GitModifyCommandTest extends GitModifyCommandTestBase {
assertInTree(assertions);
}
@Test(expected = AlreadyExistsException.class)
public void shouldFailMoveAndKeepFilesWhenSourceAndTargetAreTheSame() {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = prepareModifyCommandRequest();
request.addRequest(new ModifyCommandRequest.MoveRequest("c", "c", false));
command.execute(request);
}
private ModifyCommandRequest prepareModifyCommandRequest() {
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("Make some change");
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
return request;
}
}

View File

@@ -102,7 +102,7 @@ public class GitModifyCommand_LFSTest extends GitModifyCommandTestBase {
GitModifyCommand command = createCommand();
ModifyCommandRequest request = new ModifyCommandRequest();
request.setCommitMessage("Move file");
request.addRequest(new ModifyCommandRequest.MoveRequest("new_lfs.png", "moved_lfs.png"));
request.addRequest(new ModifyCommandRequest.MoveRequest("new_lfs.png", "moved_lfs.png", false));
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
command.execute(request);