diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java index d8c0ff1c60..6066b66371 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitCommand.java @@ -43,6 +43,7 @@ import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.repository.GitUtil; @@ -55,7 +56,10 @@ import sonia.scm.user.User; import java.io.IOException; import java.util.Optional; import java.util.function.Function; +import java.util.function.Supplier; +import static java.util.Optional.empty; +import static java.util.Optional.of; import static sonia.scm.ContextEntry.ContextBuilder.entity; import static sonia.scm.NotFoundException.notFound; @@ -200,14 +204,26 @@ class AbstractGitCommand } } - void doCommit(String message, Person author) { + void failIfNotChanged(Supplier doThrow) { + try { + if (clone.status().call().isClean()) { + throw doThrow.get(); + } + } catch (GitAPIException e) { + throw new InternalRepositoryException(context.getRepository(), "could not read status of repository", e); + } + } + + Optional doCommit(String message, Person author) { Person authorToUse = determineAuthor(author); try { if (!clone.status().call().isClean()) { - clone.commit() + return of(clone.commit() .setAuthor(authorToUse.getName(), authorToUse.getMail()) .setMessage(message) - .call(); + .call()); + } else { + return empty(); } } catch (GitAPIException e) { throw new InternalRepositoryException(context.getRepository(), "could not commit changes", e); diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java index 2c473398c5..c86c94aea1 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java @@ -2,6 +2,8 @@ package sonia.scm.repository.spi; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; +import sonia.scm.BadRequestException; +import sonia.scm.ContextEntry; import sonia.scm.repository.GitWorkdirFactory; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Repository; @@ -44,9 +46,10 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman @Override String run() throws IOException { checkOutBranch(request.getBranch()); - for (ModifyCommandRequest.PartialRequest r: request.getRequests()) { + for (ModifyCommandRequest.PartialRequest r : request.getRequests()) { r.execute(this); } + failIfNotChanged(NoChangesMadeException::new); doCommit(request.getCommitMessage(), request.getAuthor()); push(); return getClone().getRepository().getRefDatabase().findRef("HEAD").getObjectId().name(); @@ -86,6 +89,17 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman public void move(String sourcePath, String targetPath) { } + + private class NoChangesMadeException extends BadRequestException { + public NoChangesMadeException() { + super(ContextEntry.ContextBuilder.entity(context.getRepository()).build(), "no changes detected to branch " + ModifyWorker.this.request.getBranch()); + } + + @Override + public String getCode() { + return "40RaYIeeR1"; + } + } } private String throwInternalRepositoryException(String message, Exception e) { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java index 2d9f5d0235..c1e1c05631 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java @@ -14,6 +14,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import sonia.scm.AlreadyExistsException; +import sonia.scm.BadRequestException; import sonia.scm.repository.Person; import sonia.scm.repository.util.WorkdirProvider; @@ -108,6 +109,21 @@ public class GitModifyCommandTest extends AbstractGitCommandTestBase { assertInTree(assertions); } + @Test(expected = BadRequestException.class) + public void shouldFailIfNoChangesMade() throws IOException, GitAPIException { + File newFile = Files.write(temporaryFolder.newFile().toPath(), "b\n".getBytes()).toFile(); + + GitModifyCommand command = createCommand(); + + ModifyCommandRequest request = new ModifyCommandRequest(); + request.setBranch("master"); + request.setCommitMessage("test commit"); + request.addRequest(new ModifyCommandRequest.CreateFileRequest("b.txt", newFile, true)); + request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det")); + + command.execute(request); + } + private void assertInTree(TreeAssertions assertions) throws IOException, GitAPIException { try (Git git = new Git(createContext().open())) { RevCommit lastCommit = getLastCommit(git); diff --git a/scm-webapp/src/main/resources/locales/de/plugins.json b/scm-webapp/src/main/resources/locales/de/plugins.json index bf534dc138..9c5bb3f5f5 100644 --- a/scm-webapp/src/main/resources/locales/de/plugins.json +++ b/scm-webapp/src/main/resources/locales/de/plugins.json @@ -171,6 +171,10 @@ "thbsUFokjk": { "displayName": "Unerlaubte Änderung eines Schlüsselwerts", "description": "Ein Schlüsselwert wurde unerlaubterweise geändert." + }, + "40RaYIeeR1": { + "displayName": "Es wurden keine Änderungen durchgeführt", + "description": "Das Repository wurde nicht verändert. Daher konnte kein neuer Commit erzeugt werden." } }, "namespaceStrategies": { diff --git a/scm-webapp/src/main/resources/locales/en/plugins.json b/scm-webapp/src/main/resources/locales/en/plugins.json index 471da10159..1ffffd73b7 100644 --- a/scm-webapp/src/main/resources/locales/en/plugins.json +++ b/scm-webapp/src/main/resources/locales/en/plugins.json @@ -171,6 +171,10 @@ "thbsUFokjk": { "displayName": "Illegal change of an identifier", "description": "A identifier value has been changed in the entity. This is not allowed." + }, + "40RaYIeeR1": { + "displayName": "No changes were made", + "description": "No changes were made to the files of the repository. Therefor no new commit could be created." } }, "namespaceStrategies": {