mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-13 17:05:43 +01:00
Merged in feature/harmonize_branches_in_changesets (pull request #81)
Add branch to changeset collections
This commit is contained in:
@@ -82,6 +82,22 @@ public class ChangesetPagingResult implements Iterable<Changeset>, Serializable
|
|||||||
{
|
{
|
||||||
this.total = total;
|
this.total = total;
|
||||||
this.changesets = changesets;
|
this.changesets = changesets;
|
||||||
|
this.branchName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new changeset paging result for a specific branch.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param total total number of changesets
|
||||||
|
* @param changesets current list of fetched changesets
|
||||||
|
* @param branchName branch name this result was created for
|
||||||
|
*/
|
||||||
|
public ChangesetPagingResult(int total, List<Changeset> changesets, String branchName)
|
||||||
|
{
|
||||||
|
this.total = total;
|
||||||
|
this.changesets = changesets;
|
||||||
|
this.branchName = branchName;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -158,6 +174,7 @@ public class ChangesetPagingResult implements Iterable<Changeset>, Serializable
|
|||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
.add("changesets", changesets)
|
.add("changesets", changesets)
|
||||||
.add("total", total)
|
.add("total", total)
|
||||||
|
.add("branch", branchName)
|
||||||
.toString();
|
.toString();
|
||||||
//J+
|
//J+
|
||||||
}
|
}
|
||||||
@@ -186,37 +203,35 @@ public class ChangesetPagingResult implements Iterable<Changeset>, Serializable
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- set methods ----------------------------------------------------------
|
void setChangesets(List<Changeset> changesets)
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current list of changesets.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param changesets current list of changesets
|
|
||||||
*/
|
|
||||||
public void setChangesets(List<Changeset> changesets)
|
|
||||||
{
|
{
|
||||||
this.changesets = changesets;
|
this.changesets = changesets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void setTotal(int total)
|
||||||
* Sets the total number of changesets
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param total total number of changesets
|
|
||||||
*/
|
|
||||||
public void setTotal(int total)
|
|
||||||
{
|
{
|
||||||
this.total = total;
|
this.total = total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBranchName(String branchName) {
|
||||||
|
this.branchName = branchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the branch name this result was created for. This can either be an explicit branch ("give me all
|
||||||
|
* changesets for branch xyz") or an implicit one ("give me the changesets for the default").
|
||||||
|
*/
|
||||||
|
public String getBranchName() {
|
||||||
|
return branchName;
|
||||||
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
/** current list of changesets */
|
|
||||||
@XmlElement(name = "changeset")
|
@XmlElement(name = "changeset")
|
||||||
@XmlElementWrapper(name = "changesets")
|
@XmlElementWrapper(name = "changesets")
|
||||||
private List<Changeset> changesets;
|
private List<Changeset> changesets;
|
||||||
|
|
||||||
/** total number of changesets */
|
|
||||||
private int total;
|
private int total;
|
||||||
|
|
||||||
|
private String branchName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.PersonIdent;
|
import org.eclipse.jgit.lib.PersonIdent;
|
||||||
import org.eclipse.jgit.lib.Ref;
|
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||||
@@ -51,8 +50,8 @@ import java.io.Closeable;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -130,27 +129,9 @@ public class GitChangesetConverter implements Closeable
|
|||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public Changeset createChangeset(RevCommit commit) throws IOException
|
public Changeset createChangeset(RevCommit commit)
|
||||||
{
|
{
|
||||||
List<String> branches = Lists.newArrayList();
|
return createChangeset(commit, Collections.emptyList());
|
||||||
Set<Ref> refs = repository.getAllRefsByPeeledObjectId().get(commit.getId());
|
|
||||||
|
|
||||||
if (Util.isNotEmpty(refs))
|
|
||||||
{
|
|
||||||
|
|
||||||
for (Ref ref : refs)
|
|
||||||
{
|
|
||||||
String branch = GitUtil.getBranch(ref);
|
|
||||||
|
|
||||||
if (branch != null)
|
|
||||||
{
|
|
||||||
branches.add(branch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return createChangeset(commit, branches);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,7 +146,6 @@ public class GitChangesetConverter implements Closeable
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public Changeset createChangeset(RevCommit commit, String branch)
|
public Changeset createChangeset(RevCommit commit, String branch)
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
return createChangeset(commit, Lists.newArrayList(branch));
|
return createChangeset(commit, Lists.newArrayList(branch));
|
||||||
}
|
}
|
||||||
@@ -183,7 +163,6 @@ public class GitChangesetConverter implements Closeable
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public Changeset createChangeset(RevCommit commit, List<String> branches)
|
public Changeset createChangeset(RevCommit commit, List<String> branches)
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
String id = commit.getId().name();
|
String id = commit.getId().name();
|
||||||
List<String> parentList = null;
|
List<String> parentList = null;
|
||||||
|
|||||||
@@ -63,8 +63,11 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static java.util.Optional.of;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -345,12 +348,11 @@ public final class GitUtil
|
|||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static ObjectId getBranchId(org.eclipse.jgit.lib.Repository repo,
|
public static Ref getBranchId(org.eclipse.jgit.lib.Repository repo,
|
||||||
String branchName)
|
String branchName)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
ObjectId branchId = null;
|
Ref ref = null;
|
||||||
|
|
||||||
if (!branchName.startsWith(REF_HEAD))
|
if (!branchName.startsWith(REF_HEAD))
|
||||||
{
|
{
|
||||||
branchName = PREFIX_HEADS.concat(branchName);
|
branchName = PREFIX_HEADS.concat(branchName);
|
||||||
@@ -360,24 +362,19 @@ public final class GitUtil
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Ref ref = repo.findRef(branchName);
|
ref = repo.findRef(branchName);
|
||||||
|
|
||||||
if (ref != null)
|
if (ref == null)
|
||||||
{
|
|
||||||
branchId = ref.getObjectId();
|
|
||||||
}
|
|
||||||
else if (logger.isWarnEnabled())
|
|
||||||
{
|
{
|
||||||
logger.warn("could not find branch for {}", branchName);
|
logger.warn("could not find branch for {}", branchName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
logger.warn("error occured during resolve of branch id", ex);
|
logger.warn("error occured during resolve of branch id", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return branchId;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -499,68 +496,48 @@ public final class GitUtil
|
|||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static ObjectId getRepositoryHead(org.eclipse.jgit.lib.Repository repo) {
|
||||||
* Method description
|
return getRepositoryHeadRef(repo).map(Ref::getObjectId).orElse(null);
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param repo
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static ObjectId getRepositoryHead(org.eclipse.jgit.lib.Repository repo)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
ObjectId id = null;
|
|
||||||
String head = null;
|
|
||||||
Map<String, Ref> refs = repo.getAllRefs();
|
|
||||||
|
|
||||||
for (Map.Entry<String, Ref> e : refs.entrySet())
|
|
||||||
{
|
|
||||||
String key = e.getKey();
|
|
||||||
|
|
||||||
if (REF_HEAD.equals(key))
|
|
||||||
{
|
|
||||||
head = REF_HEAD;
|
|
||||||
id = e.getValue().getObjectId();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (key.startsWith(REF_HEAD_PREFIX))
|
|
||||||
{
|
|
||||||
id = e.getValue().getObjectId();
|
|
||||||
head = key.substring(REF_HEAD_PREFIX.length());
|
|
||||||
|
|
||||||
if (REF_MASTER.equals(head))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == null)
|
public static Optional<Ref> getRepositoryHeadRef(org.eclipse.jgit.lib.Repository repo) {
|
||||||
{
|
Optional<Ref> foundRef = findMostAppropriateHead(repo.getAllRefs());
|
||||||
id = repo.resolve(Constants.HEAD);
|
|
||||||
|
if (foundRef.isPresent()) {
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("use {}:{} as repository head for directory {}",
|
||||||
|
foundRef.map(GitUtil::getBranch).orElse(null),
|
||||||
|
foundRef.map(Ref::getObjectId).map(ObjectId::name).orElse(null),
|
||||||
|
repo.getDirectory());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn("could not find repository head in directory {}", repo.getDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
return foundRef;
|
||||||
{
|
|
||||||
if ((head != null) && (id != null))
|
|
||||||
{
|
|
||||||
logger.debug("use {}:{} as repository head", head, id.name());
|
|
||||||
}
|
|
||||||
else if (id != null)
|
|
||||||
{
|
|
||||||
logger.debug("use {} as repository head", id.name());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.warn("could not find repository head");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
private static Optional<Ref> findMostAppropriateHead(Map<String, Ref> refs) {
|
||||||
|
Ref refHead = refs.get(REF_HEAD);
|
||||||
|
if (refHead != null && refHead.isSymbolic() && isBranch(refHead.getTarget().getName())) {
|
||||||
|
return of(refHead.getTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref master = refs.get(REF_HEAD_PREFIX + REF_MASTER);
|
||||||
|
if (master != null) {
|
||||||
|
return of(master);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref develop = refs.get(REF_HEAD_PREFIX + "develop");
|
||||||
|
if (develop != null) {
|
||||||
|
return of(develop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return refs.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(e -> e.getKey().startsWith(REF_HEAD_PREFIX))
|
||||||
|
.map(Map.Entry::getValue)
|
||||||
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,19 +34,20 @@ package sonia.scm.repository.spi;
|
|||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
|
import org.eclipse.jgit.lib.Ref;
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import sonia.scm.repository.GitConstants;
|
import sonia.scm.repository.GitConstants;
|
||||||
import sonia.scm.repository.GitUtil;
|
import sonia.scm.repository.GitUtil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Sebastian Sdorra
|
* @author Sebastian Sdorra
|
||||||
@@ -98,26 +99,28 @@ public class AbstractGitCommand
|
|||||||
return commit;
|
return commit;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObjectId getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException {
|
protected ObjectId getDefaultBranch(Repository gitRepository) throws IOException {
|
||||||
ObjectId head;
|
Ref ref = getBranchOrDefault(gitRepository, null);
|
||||||
if ( Strings.isNullOrEmpty(requestedBranch) ) {
|
if (ref == null) {
|
||||||
head = getDefaultBranch(gitRepository);
|
return null;
|
||||||
} else {
|
} else {
|
||||||
head = GitUtil.getBranchId(gitRepository, requestedBranch);
|
return ref.getObjectId();
|
||||||
}
|
}
|
||||||
return head;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObjectId getDefaultBranch(Repository gitRepository) throws IOException {
|
protected Ref getBranchOrDefault(Repository gitRepository, String requestedBranch) throws IOException {
|
||||||
ObjectId head;
|
if ( Strings.isNullOrEmpty(requestedBranch) ) {
|
||||||
String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH);
|
String defaultBranchName = repository.getProperty(GitConstants.PROPERTY_DEFAULT_BRANCH);
|
||||||
if (!Strings.isNullOrEmpty(defaultBranchName)) {
|
if (!Strings.isNullOrEmpty(defaultBranchName)) {
|
||||||
head = GitUtil.getBranchId(gitRepository, defaultBranchName);
|
return GitUtil.getBranchId(gitRepository, defaultBranchName);
|
||||||
} else {
|
} else {
|
||||||
logger.trace("no default branch configured, use repository head as default");
|
logger.trace("no default branch configured, use repository head as default");
|
||||||
head = GitUtil.getRepositoryHead(gitRepository);
|
Optional<Ref> repositoryHeadRef = GitUtil.getRepositoryHeadRef(gitRepository);
|
||||||
|
return repositoryHeadRef.orElse(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return GitUtil.getBranchId(gitRepository, requestedBranch);
|
||||||
}
|
}
|
||||||
return head;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import com.google.common.base.Strings;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.eclipse.jgit.errors.MissingObjectException;
|
import org.eclipse.jgit.errors.MissingObjectException;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
|
import org.eclipse.jgit.lib.Ref;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
@@ -170,8 +171,8 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
GitChangesetConverter converter = null;
|
GitChangesetConverter converter = null;
|
||||||
RevWalk revWalk = null;
|
RevWalk revWalk = null;
|
||||||
|
|
||||||
try (org.eclipse.jgit.lib.Repository gr = open()) {
|
try (org.eclipse.jgit.lib.Repository repository = open()) {
|
||||||
if (!gr.getAllRefs().isEmpty()) {
|
if (!repository.getAllRefs().isEmpty()) {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
int start = request.getPagingStart();
|
int start = request.getPagingStart();
|
||||||
|
|
||||||
@@ -188,18 +189,18 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
ObjectId startId = null;
|
ObjectId startId = null;
|
||||||
|
|
||||||
if (!Strings.isNullOrEmpty(request.getStartChangeset())) {
|
if (!Strings.isNullOrEmpty(request.getStartChangeset())) {
|
||||||
startId = gr.resolve(request.getStartChangeset());
|
startId = repository.resolve(request.getStartChangeset());
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectId endId = null;
|
ObjectId endId = null;
|
||||||
|
|
||||||
if (!Strings.isNullOrEmpty(request.getEndChangeset())) {
|
if (!Strings.isNullOrEmpty(request.getEndChangeset())) {
|
||||||
endId = gr.resolve(request.getEndChangeset());
|
endId = repository.resolve(request.getEndChangeset());
|
||||||
}
|
}
|
||||||
|
|
||||||
revWalk = new RevWalk(gr);
|
revWalk = new RevWalk(repository);
|
||||||
|
|
||||||
converter = new GitChangesetConverter(gr, revWalk);
|
converter = new GitChangesetConverter(repository, revWalk);
|
||||||
|
|
||||||
if (!Strings.isNullOrEmpty(request.getPath())) {
|
if (!Strings.isNullOrEmpty(request.getPath())) {
|
||||||
revWalk.setTreeFilter(
|
revWalk.setTreeFilter(
|
||||||
@@ -207,13 +208,13 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF));
|
PathFilter.create(request.getPath()), TreeFilter.ANY_DIFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectId head = getBranchOrDefault(gr, request.getBranch());
|
Ref branch = getBranchOrDefault(repository,request.getBranch());
|
||||||
|
|
||||||
if (head != null) {
|
if (branch != null) {
|
||||||
if (startId != null) {
|
if (startId != null) {
|
||||||
revWalk.markStart(revWalk.lookupCommit(startId));
|
revWalk.markStart(revWalk.lookupCommit(startId));
|
||||||
} else {
|
} else {
|
||||||
revWalk.markStart(revWalk.lookupCommit(head));
|
revWalk.markStart(revWalk.lookupCommit(branch.getObjectId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator<RevCommit> iterator = revWalk.iterator();
|
Iterator<RevCommit> iterator = revWalk.iterator();
|
||||||
@@ -234,10 +235,14 @@ public class GitLogCommand extends AbstractGitCommand implements LogCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (branch != null) {
|
||||||
|
changesets = new ChangesetPagingResult(counter, changesetList, GitUtil.getBranch(branch.getName()));
|
||||||
|
} else {
|
||||||
changesets = new ChangesetPagingResult(counter, changesetList);
|
changesets = new ChangesetPagingResult(counter, changesetList);
|
||||||
|
}
|
||||||
} else if (logger.isWarnEnabled()) {
|
} else if (logger.isWarnEnabled()) {
|
||||||
logger.warn("the repository {} seems to be empty",
|
logger.warn("the repository {} seems to be empty",
|
||||||
repository.getName());
|
this.repository.getName());
|
||||||
|
|
||||||
changesets = new ChangesetPagingResult(0, Collections.EMPTY_LIST);
|
changesets = new ChangesetPagingResult(0, Collections.EMPTY_LIST);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2010, Sebastian Sdorra
|
* Copyright (c) 2010, Sebastian Sdorra
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@@ -33,14 +34,17 @@
|
|||||||
|
|
||||||
package sonia.scm.repository.spi;
|
package sonia.scm.repository.spi;
|
||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import sonia.scm.repository.Changeset;
|
import sonia.scm.repository.Changeset;
|
||||||
import sonia.scm.repository.ChangesetPagingResult;
|
import sonia.scm.repository.ChangesetPagingResult;
|
||||||
import sonia.scm.repository.GitConstants;
|
import sonia.scm.repository.GitConstants;
|
||||||
import sonia.scm.repository.Modifications;
|
import sonia.scm.repository.Modifications;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static java.nio.charset.Charset.defaultCharset;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
@@ -48,8 +52,6 @@ import static org.junit.Assert.assertNotNull;
|
|||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link GitLogCommand}.
|
* Unit tests for {@link GitLogCommand}.
|
||||||
*
|
*
|
||||||
@@ -72,6 +74,8 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
|
|||||||
assertEquals("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1", result.getChangesets().get(1).getId());
|
assertEquals("86a6645eceefe8b9a247db5eb16e3d89a7e6e6d1", result.getChangesets().get(1).getId());
|
||||||
assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(2).getId());
|
assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(2).getId());
|
||||||
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(3).getId());
|
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(3).getId());
|
||||||
|
assertEquals("master", result.getBranchName());
|
||||||
|
assertTrue(result.getChangesets().stream().allMatch(r -> r.getBranches().isEmpty()));
|
||||||
|
|
||||||
// set default branch and fetch again
|
// set default branch and fetch again
|
||||||
repository.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "test-branch");
|
repository.setProperty(GitConstants.PROPERTY_DEFAULT_BRANCH, "test-branch");
|
||||||
@@ -79,10 +83,12 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
|
|||||||
result = createCommand().getChangesets(new LogCommandRequest());
|
result = createCommand().getChangesets(new LogCommandRequest());
|
||||||
|
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
|
assertEquals("test-branch", result.getBranchName());
|
||||||
assertEquals(3, result.getTotal());
|
assertEquals(3, result.getTotal());
|
||||||
assertEquals("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", result.getChangesets().get(0).getId());
|
assertEquals("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", result.getChangesets().get(0).getId());
|
||||||
assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(1).getId());
|
assertEquals("592d797cd36432e591416e8b2b98154f4f163411", result.getChangesets().get(1).getId());
|
||||||
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(2).getId());
|
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", result.getChangesets().get(2).getId());
|
||||||
|
assertTrue(result.getChangesets().stream().allMatch(r -> r.getBranches().isEmpty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -210,6 +216,32 @@ public class GitLogCommandTest extends AbstractGitCommandTestBase
|
|||||||
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", c2.getId());
|
assertEquals("435df2f061add3589cb326cc64be9b9c3897ceca", c2.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFindDefaultBranchFromHEAD() throws Exception {
|
||||||
|
setRepositoryHeadReference("ref: refs/heads/test-branch");
|
||||||
|
|
||||||
|
ChangesetPagingResult changesets = createCommand().getChangesets(new LogCommandRequest());
|
||||||
|
|
||||||
|
assertEquals("test-branch", changesets.getBranchName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFindMasterBranchWhenHEADisNoRef() throws Exception {
|
||||||
|
setRepositoryHeadReference("592d797cd36432e591416e8b2b98154f4f163411");
|
||||||
|
|
||||||
|
ChangesetPagingResult changesets = createCommand().getChangesets(new LogCommandRequest());
|
||||||
|
|
||||||
|
assertEquals("master", changesets.getBranchName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRepositoryHeadReference(String s) throws IOException {
|
||||||
|
Files.write(s, repositoryHeadReferenceFile(), defaultCharset());
|
||||||
|
}
|
||||||
|
|
||||||
|
private File repositoryHeadReferenceFile() {
|
||||||
|
return new File(repositoryDirectory, "HEAD");
|
||||||
|
}
|
||||||
|
|
||||||
private GitLogCommand createCommand()
|
private GitLogCommand createCommand()
|
||||||
{
|
{
|
||||||
return new GitLogCommand(createContext(), repository);
|
return new GitLogCommand(createContext(), repository);
|
||||||
|
|||||||
@@ -132,7 +132,11 @@ public class HgLogCommand extends AbstractCommand implements LogCommand
|
|||||||
List<Changeset> changesets = on(repository).rev(start + ":"
|
List<Changeset> changesets = on(repository).rev(start + ":"
|
||||||
+ end).execute();
|
+ end).execute();
|
||||||
|
|
||||||
|
if (request.getBranch() == null) {
|
||||||
result = new ChangesetPagingResult(total, changesets);
|
result = new ChangesetPagingResult(total, changesets);
|
||||||
|
} else {
|
||||||
|
result = new ChangesetPagingResult(total, changesets, request.getBranch());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -216,10 +216,7 @@ public abstract class AbstractChangesetCommand extends AbstractCommand
|
|||||||
|
|
||||||
String branch = in.textUpTo('\n');
|
String branch = in.textUpTo('\n');
|
||||||
|
|
||||||
if (!BRANCH_DEFAULT.equals(branch))
|
|
||||||
{
|
|
||||||
changeset.getBranches().add(branch);
|
changeset.getBranches().add(branch);
|
||||||
}
|
|
||||||
|
|
||||||
String p1 = readId(in, changeset, PROPERTY_PARENT1_REVISION);
|
String p1 = readId(in, changeset, PROPERTY_PARENT1_REVISION);
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,21 @@ public class HgLogCommandTest extends AbstractHgCommandTestBase
|
|||||||
result.getChangesets().get(2).getId());
|
result.getChangesets().get(2).getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetDefaultBranchInfo() {
|
||||||
|
LogCommandRequest request = new LogCommandRequest();
|
||||||
|
|
||||||
|
request.setPath("a.txt");
|
||||||
|
|
||||||
|
ChangesetPagingResult result = createComamnd().getChangesets(request);
|
||||||
|
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(1,
|
||||||
|
result.getChangesets().get(0).getBranches().size());
|
||||||
|
assertEquals("default",
|
||||||
|
result.getChangesets().get(0).getBranches().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAllWithLimit() {
|
public void testGetAllWithLimit() {
|
||||||
LogCommandRequest request = new LogCommandRequest();
|
LogCommandRequest request = new LogCommandRequest();
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ public class BranchChangesetCollectionToDtoMapper extends ChangesetCollectionToD
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BranchChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
public BranchChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||||
super(changesetToChangesetDtoMapper);
|
super(changesetToChangesetDtoMapper, resourceLinks);
|
||||||
this.resourceLinks = resourceLinks;
|
this.resourceLinks = resourceLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, String branch) {
|
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, String branch) {
|
||||||
return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch));
|
return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch), branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createSelfLink(Repository repository, String branch) {
|
private String createSelfLink(Repository repository, String branch) {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import de.otto.edison.hal.HalRepresentation;
|
||||||
|
import de.otto.edison.hal.Links;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@NoArgsConstructor @AllArgsConstructor @Getter @Setter
|
||||||
|
public class BranchReferenceDto extends HalRepresentation {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
||||||
|
protected HalRepresentation add(Links links) {
|
||||||
|
return super.add(links);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,10 +12,13 @@ public class ChangesetCollectionToDtoMapper extends ChangesetCollectionToDtoMapp
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||||
super(changesetToChangesetDtoMapper);
|
super(changesetToChangesetDtoMapper, resourceLinks);
|
||||||
this.resourceLinks = resourceLinks;
|
this.resourceLinks = resourceLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, String branchName) {
|
||||||
|
return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository), branchName);
|
||||||
|
}
|
||||||
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository) {
|
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository) {
|
||||||
return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository));
|
return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import de.otto.edison.hal.Links;
|
||||||
import sonia.scm.PageResult;
|
import sonia.scm.PageResult;
|
||||||
import sonia.scm.repository.Changeset;
|
import sonia.scm.repository.Changeset;
|
||||||
import sonia.scm.repository.Repository;
|
import sonia.scm.repository.Repository;
|
||||||
@@ -10,14 +11,28 @@ import java.util.function.Supplier;
|
|||||||
class ChangesetCollectionToDtoMapperBase extends PagedCollectionToDtoMapper<Changeset, ChangesetDto> {
|
class ChangesetCollectionToDtoMapperBase extends PagedCollectionToDtoMapper<Changeset, ChangesetDto> {
|
||||||
|
|
||||||
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
|
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
|
||||||
|
private final ResourceLinks resourceLinks;
|
||||||
|
|
||||||
ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) {
|
ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||||
super("changesets");
|
super("changesets");
|
||||||
this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper;
|
this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper;
|
||||||
|
this.resourceLinks = resourceLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, Supplier<String> selfLinkSupplier) {
|
CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, Supplier<String> selfLinkSupplier) {
|
||||||
return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
|
return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, Supplier<String> selfLinkSupplier, String branchName) {
|
||||||
|
CollectionDto collectionDto = this.map(pageNumber, pageSize, pageResult, repository, selfLinkSupplier);
|
||||||
|
collectionDto.withEmbedded("branch", createBranchReferenceDto(repository, branchName));
|
||||||
|
return collectionDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BranchReferenceDto createBranchReferenceDto(Repository repository, String branchName) {
|
||||||
|
BranchReferenceDto branchReferenceDto = new BranchReferenceDto();
|
||||||
|
branchReferenceDto.setName(branchName);
|
||||||
|
branchReferenceDto.add(Links.linkingTo().self(resourceLinks.branch().self(repository.getNamespaceAndName(), branchName)).build());
|
||||||
|
return branchReferenceDto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,7 +65,11 @@ public class ChangesetRootResource {
|
|||||||
.getChangesets();
|
.getChangesets();
|
||||||
if (changesets != null && changesets.getChangesets() != null) {
|
if (changesets != null && changesets.getChangesets() != null) {
|
||||||
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
|
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
|
||||||
|
if (changesets.getBranchName() != null) {
|
||||||
|
return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository, changesets.getBranchName())).build();
|
||||||
|
} else {
|
||||||
return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build();
|
return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,4 +15,9 @@ class CollectionDto extends HalRepresentation {
|
|||||||
CollectionDto(Links links, Embedded embedded) {
|
CollectionDto(Links links, Embedded embedded) {
|
||||||
super(links, embedded);
|
super(links, embedded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HalRepresentation withEmbedded(String rel, HalRepresentation embeddedItem) {
|
||||||
|
return super.withEmbedded(rel, embeddedItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMa
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public FileHistoryCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
public FileHistoryCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||||
super(changesetToChangesetDtoMapper);
|
super(changesetToChangesetDtoMapper, resourceLinks);
|
||||||
this.resourceLinks = resourceLinks;
|
this.resourceLinks = resourceLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.junit.Test;
|
||||||
|
import sonia.scm.PageResult;
|
||||||
|
import sonia.scm.repository.Changeset;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class ChangesetCollectionToDtoMapperTest {
|
||||||
|
|
||||||
|
public static final Repository REPOSITORY = new Repository("", "git", "space", "name");
|
||||||
|
public static final Changeset CHANGESET = new Changeset();
|
||||||
|
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper = mock(ChangesetToChangesetDtoMapper.class);
|
||||||
|
|
||||||
|
private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, ResourceLinksMock.createMock(URI.create("/")));
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldMapCollectionEntries() {
|
||||||
|
ChangesetDto expectedChangesetDto = new ChangesetDto();
|
||||||
|
when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto);
|
||||||
|
|
||||||
|
CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY);
|
||||||
|
|
||||||
|
assertThat(collectionDto.getEmbedded().hasItem("changesets")).isTrue();
|
||||||
|
assertThat(collectionDto.getEmbedded().getItemsBy("changesets")).containsExactly(expectedChangesetDto);
|
||||||
|
assertThat(collectionDto.getEmbedded().hasItem("branch")).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotEmbedBranchIfNotSpecified() {
|
||||||
|
ChangesetDto expectedChangesetDto = new ChangesetDto();
|
||||||
|
when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto);
|
||||||
|
|
||||||
|
CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY);
|
||||||
|
|
||||||
|
assertThat(collectionDto.getEmbedded().hasItem("branch")).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldEmbedBranchIfSpecified() {
|
||||||
|
ChangesetDto expectedChangesetDto = new ChangesetDto();
|
||||||
|
when(changesetToChangesetDtoMapper.map(CHANGESET, REPOSITORY)).thenReturn(expectedChangesetDto);
|
||||||
|
|
||||||
|
CollectionDto collectionDto = changesetCollectionToDtoMapper.map(0, 1, new PageResult<>(asList(CHANGESET), 1), REPOSITORY, "someBranch");
|
||||||
|
|
||||||
|
assertThat(collectionDto.getEmbedded().hasItem("branch")).isTrue();
|
||||||
|
assertThat(collectionDto.getEmbedded().getItemsBy("branch"))
|
||||||
|
.hasSize(1)
|
||||||
|
.first().matches(b -> b.getLinks().getLinkBy("self").isPresent())
|
||||||
|
.extracting(b -> b.getLinks().getLinkBy("self").get().getHref()).first().isEqualTo("/v2/repositories/space/name/branches/someBranch");
|
||||||
|
assertThat(collectionDto.getEmbedded().getItemsBy("branch"))
|
||||||
|
.first().extracting("name").first().isEqualTo("someBranch");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user