diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 8172ecc584..9eff0c4f99 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -39,6 +39,9 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; +import org.eclipse.jgit.api.FetchCommand; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.diff.DiffFormatter; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -48,6 +51,8 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.transport.FetchResult; +import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.FS; @@ -62,6 +67,7 @@ import java.io.File; import java.io.IOException; import java.util.Map; +import java.util.concurrent.TimeUnit; /** * @@ -85,6 +91,15 @@ public final class GitUtil /** Field description */ private static final String PREFIX_TAG = "refs/tags/"; + /** Field description */ + private static final String REFSPEC = "+refs/heads/*:refs/remote/scm/%s/*"; + + /** Field description */ + private static final String REMOTE_REF = "refs/remote/scm/%s/%s"; + + /** Field description */ + private static final int TIMEOUT = 5; + /** the logger for GitUtil */ private static final Logger logger = LoggerFactory.getLogger(GitUtil.class); @@ -160,6 +175,40 @@ public final class GitUtil return tags; } + /** + * Method description + * + * + * @param git + * @param directory + * @param remoteRepository + * + * @return + * + * @throws GitAPIException + * + * @throws RepositoryException + */ + public static FetchResult fetch(Git git, File directory, + Repository remoteRepository) + throws RepositoryException + { + try + { + FetchCommand fetch = git.fetch(); + + fetch.setRemote(directory.getAbsolutePath()); + fetch.setRefSpecs(createRefSpec(remoteRepository)); + fetch.setTimeout((int) TimeUnit.MINUTES.toSeconds(TIMEOUT)); + + return fetch.call(); + } + catch (GitAPIException ex) + { + throw new RepositoryException("could not fetch", ex); + } + } + /** * Method description * @@ -522,6 +571,36 @@ public final class GitUtil return revId; } + /** + * Method description + * + * + * @param repository + * @param localBranch + * + * @return + */ + public static String getScmRemoteRefName(Repository repository, + Ref localBranch) + { + return getScmRemoteRefName(repository, localBranch.getName()); + } + + /** + * Method description + * + * + * @param repository + * @param localBranch + * + * @return + */ + public static String getScmRemoteRefName(Repository repository, + String localBranch) + { + return String.format(REMOTE_REF, repository.getId(), localBranch); + } + /** * Method description * @@ -575,4 +654,17 @@ public final class GitUtil } } } + + /** + * Method description + * + * + * @param repository + * + * @return + */ + private static RefSpec createRefSpec(Repository repository) + { + return new RefSpec(String.format(REFSPEC, repository.getId())); + } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java index 9262166237..f230bdc27f 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommand.java @@ -36,14 +36,11 @@ package sonia.scm.repository.spi; import com.google.common.collect.Lists; import com.google.common.io.Closeables; -import org.eclipse.jgit.api.FetchCommand; import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; -import org.eclipse.jgit.transport.RefSpec; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; @@ -59,7 +56,6 @@ import java.io.IOException; import java.util.List; import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; /** * @@ -69,18 +65,9 @@ public abstract class AbstractGitIncomingOutgoingCommand extends AbstractGitCommand { - /** Field description */ - private static final String REFSPEC = "+refs/heads/*:refs/remote/scm/%s/*"; - - /** Field description */ - private static final String REMOTE_REF = "refs/remote/scm/%s/%s"; - /** Field description */ private static final String REMOTE_REF_PREFIX = "refs/remote/scm/%s/"; - /** Field description */ - private static final int TIMEOUT = 5; - //~--- constructors --------------------------------------------------------- /** @@ -115,6 +102,18 @@ public abstract class AbstractGitIncomingOutgoingCommand ObjectId remoteId) throws IOException; + /** + * Method description + * + * + * @param localId + * @param remoteId + * + * @return + */ + protected abstract boolean retrieveChangesets(ObjectId localId, + ObjectId remoteId); + //~--- get methods ---------------------------------------------------------- /** @@ -135,29 +134,17 @@ public abstract class AbstractGitIncomingOutgoingCommand Repository remoteRepository = request.getRemoteRepository(); Git git = Git.wrap(open()); - FetchCommand fetch = git.fetch(); - fetch.setRemote(handler.getDirectory(remoteRepository).getAbsolutePath()); - fetch.setRefSpecs(createRefSpec(remoteRepository)); - fetch.setTimeout((int) TimeUnit.MINUTES.toSeconds(TIMEOUT)); - - try - { - fetch.call(); - } - catch (GitAPIException ex) - { - throw new RepositoryException("could not fetch", ex); - } + GitUtil.fetch(git, handler.getDirectory(repository), remoteRepository); ObjectId localId = GitUtil.getRepositoryHead(git.getRepository()); ObjectId remoteId = null; - Ref remoteBranch = getRemoteBranch(git.getRepository(), localId, remoteRepository); - - if ( remoteBranch != null ){ + + if (remoteBranch != null) + { remoteId = remoteBranch.getObjectId(); } @@ -202,25 +189,6 @@ public abstract class AbstractGitIncomingOutgoingCommand return new ChangesetPagingResult(changesets.size(), changesets); } - - protected abstract boolean retrieveChangesets(ObjectId localId, ObjectId remoteId); - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param repository - * - * @return - */ - private RefSpec createRefSpec(Repository repository) - { - return new RefSpec(String.format(REFSPEC, repository.getId())); - } - - //~--- get methods ---------------------------------------------------------- /** * Method description @@ -247,13 +215,14 @@ public abstract class AbstractGitIncomingOutgoingCommand if (localBranch != null) { - ref = repository.getRef(getScmRemoteRefName(remoteRepository, + ref = repository.getRef(GitUtil.getScmRemoteRefName(remoteRepository, localBranch)); } } else { - ref = repository.getRef(getScmRemoteRefName(remoteRepository, "master")); + ref = repository.getRef(GitUtil.getScmRemoteRefName(remoteRepository, + "master")); if (ref == null) { @@ -280,34 +249,6 @@ public abstract class AbstractGitIncomingOutgoingCommand return ref; } - /** - * Method description - * - * - * @param repository - * @param localBranch - * - * @return - */ - private String getScmRemoteRefName(Repository repository, Ref localBranch) - { - return getScmRemoteRefName(repository, localBranch.getName()); - } - - /** - * Method description - * - * - * @param repository - * @param localBranch - * - * @return - */ - private String getScmRemoteRefName(Repository repository, String localBranch) - { - return String.format(REMOTE_REF, repository.getId(), localBranch); - } - //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPushCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPushCommand.java index 4c155fc3e6..167b83d3d8 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPushCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitPushCommand.java @@ -33,10 +33,7 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.collect.Iterables; - import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.transport.PushResult; import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.Repository; @@ -96,9 +93,8 @@ public class GitPushCommand extends AbstractGitCommand implements PushCommand try { - Iterable results = push.call(); - - response = new PushResponse(Iterables.size(results)); + push.call(); + response = new PushResponse(); } catch (Exception ex) { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommandTestBase.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractRemoteCommandTestBase.java similarity index 98% rename from scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommandTestBase.java rename to scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractRemoteCommandTestBase.java index 76d1da4598..84846edd0e 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractGitIncomingOutgoingCommandTestBase.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/AbstractRemoteCommandTestBase.java @@ -64,7 +64,7 @@ import java.io.IOException; * * @author Sebastian Sdorra */ -public class AbstractGitIncomingOutgoingCommandTestBase +public class AbstractRemoteCommandTestBase { /** diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitIncomingCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitIncomingCommandTest.java index a176eb7715..1030a4e22f 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitIncomingCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitIncomingCommandTest.java @@ -52,7 +52,7 @@ import java.io.IOException; * @author Sebastian Sdorra */ public class GitIncomingCommandTest - extends AbstractGitIncomingOutgoingCommandTestBase + extends AbstractRemoteCommandTestBase { /** diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitOutgoingCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitOutgoingCommandTest.java index 76a02703d7..80e0054c9f 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitOutgoingCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitOutgoingCommandTest.java @@ -53,7 +53,7 @@ import java.io.IOException; * @author Sebastian Sdorra */ public class GitOutgoingCommandTest - extends AbstractGitIncomingOutgoingCommandTestBase + extends AbstractRemoteCommandTestBase { /** diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitPushCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitPushCommandTest.java new file mode 100644 index 0000000000..cee2894f97 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitPushCommandTest.java @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.repository.spi; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.revwalk.RevCommit; + +import org.junit.Test; + +import sonia.scm.repository.RepositoryException; +import sonia.scm.repository.api.PushResponse; + +import static org.junit.Assert.*; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import java.util.Iterator; + +/** + * + * @author Sebastian Sdorra + */ +public class GitPushCommandTest extends AbstractRemoteCommandTestBase +{ + + /** + * Method description + * + * + * @throws GitAPIException + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testPush() + throws IOException, GitAPIException, RepositoryException + { + write(outgoing, outgoingDirectory, "a.txt", "content of a.txt"); + + RevCommit o1 = commit(outgoing, "added a"); + + write(outgoing, outgoingDirectory, "b.txt", "content of b.txt"); + + RevCommit o2 = commit(outgoing, "added b"); + + GitPushCommand cmd = createCommand(); + PushCommandRequest request = new PushCommandRequest(); + + request.setRemoteRepository(incomgingRepository); + + PushResponse response = cmd.push(request); + + assertNotNull(response); + + Iterator commits = incoming.log().call().iterator(); + + assertEquals(o2, commits.next()); + assertEquals(o1, commits.next()); + } + + /** + * Method description + * + * + * @return + */ + private GitPushCommand createCommand() + { + return new GitPushCommand(handler, new GitContext(outgoingDirectory), + outgoingRepository); + } +}