diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java index 8560ce94fc..abe5689712 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnUtil.java @@ -35,6 +35,7 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.base.Strings; import com.google.common.collect.Lists; import org.slf4j.Logger; @@ -60,6 +61,9 @@ import java.util.Map; public final class SvnUtil { + /** Field description */ + private static final String ID_TRANSACTION_PREFIX = "-1:"; + /** * svn path updated * same as modified ({@link SVNLogEntryPath#TYPE_MODIFIED})? @@ -71,6 +75,10 @@ public final class SvnUtil */ private static final Logger logger = LoggerFactory.getLogger(SvnUtil.class); + /** Field description */ + private static final String ID_TRANSACTION_PATTERN = + ID_TRANSACTION_PREFIX.concat("%s"); + //~--- constructors --------------------------------------------------------- /** @@ -224,6 +232,19 @@ public final class SvnUtil return changesets; } + /** + * Method description + * + * + * @param transaction + * + * @return + */ + public static String createTransactionEntryId(String transaction) + { + return String.format(ID_TRANSACTION_PATTERN, transaction); + } + /** * Method description * @@ -276,4 +297,30 @@ public final class SvnUtil return revisionNumber; } + + /** + * Method description + * + * + * @param id + * + * @return + */ + public static String getTransactionId(String id) + { + return id.substring(ID_TRANSACTION_PREFIX.length()); + } + + /** + * Method description + * + * + * @param id + * + * @return + */ + public static boolean isTransactionEntryId(String id) + { + return Strings.nullToEmpty(id).startsWith(ID_TRANSACTION_PREFIX); + } } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java index 5acbe5966f..af08ea929e 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnCatCommand.java @@ -30,6 +30,7 @@ */ + package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- @@ -40,6 +41,8 @@ import org.slf4j.LoggerFactory; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNProperties; import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.wc.SVNClientManager; +import org.tmatesoft.svn.core.wc.admin.SVNLookClient; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryException; @@ -93,25 +96,95 @@ public class SvnCatCommand extends AbstractSvnCommand implements CatCommand */ @Override public void getCatResult(CatCommandRequest request, OutputStream output) - throws IOException, RepositoryException + throws IOException, RepositoryException { if (logger.isDebugEnabled()) { logger.debug("try to get content for {}", request); } - long revisionNumber = SvnUtil.getRevisionNumber(request.getRevision()); + String revision = request.getRevision(); + + if (SvnUtil.isTransactionEntryId(revision)) + { + String txn = SvnUtil.getTransactionId(revision); + + getCatFromTransaction(request, output, txn); + } + else + { + + long revisionNumber = SvnUtil.getRevisionNumber(revision); + + getCatFromRevision(request, output, revisionNumber); + } + } + + /** + * Method description + * + * + * @param request + * @param output + * @param revision + * + * @throws RepositoryException + */ + private void getCatFromRevision(CatCommandRequest request, + OutputStream output, long revision) + throws RepositoryException + { + logger.debug("try to read content from revision {} and path {}", revision, + request.getPath()); try { SVNRepository svnRepository = open(); - svnRepository.getFile(request.getPath(), revisionNumber, - new SVNProperties(), output); + svnRepository.getFile(request.getPath(), revision, new SVNProperties(), + output); } catch (SVNException ex) { - logger.error("could not open repository", ex); + throw new RepositoryException("could not get content from revision", ex); + } + } + + /** + * Method description + * + * + * @param request + * @param output + * @param txn + * + * @throws RepositoryException + */ + private void getCatFromTransaction(CatCommandRequest request, + OutputStream output, String txn) + throws RepositoryException + { + logger.debug("try to read content from transaction {} and path {}", txn, + request.getPath()); + + SVNClientManager cm = null; + + try + { + cm = SVNClientManager.newInstance(); + + SVNLookClient client = cm.getLookClient(); + + client.doCat(context.getDirectory(), request.getPath(), txn, output); + } + catch (SVNException ex) + { + throw new RepositoryException("could not get content from transaction", + ex); + } + finally + { + SvnUtil.dispose(cm); } } } diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnPreReceiveHookChangesetProvier.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnPreReceiveHookChangesetProvier.java index 2a14427e78..93fb88f841 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnPreReceiveHookChangesetProvier.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnPreReceiveHookChangesetProvier.java @@ -122,6 +122,7 @@ public class SvnPreReceiveHookChangesetProvier if (entry != null) { changeset = SvnUtil.createChangeset(entry); + changeset.setId(SvnUtil.createTransactionEntryId(transaction)); clientManager.doGetChanged(repositoryDirectory, transaction, new SvnModificationHandler(changeset), true);