From 181806f84bf250c48a052166ae9bc1134133de5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 23 Nov 2020 15:10:54 +0100 Subject: [PATCH] Read last commit date for git branches --- .../repository/spi/GitBranchesCommand.java | 36 +++--- .../spi/GitBranchesCommandTest.java | 107 ++---------------- 2 files changed, 29 insertions(+), 114 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java index d026affd8b..683e5d0068 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitBranchesCommand.java @@ -24,14 +24,14 @@ package sonia.scm.repository.spi; -//~--- non-JDK imports -------------------------------------------------------- - import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import org.checkerframework.checker.nullness.qual.Nullable; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevWalk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.repository.Branch; @@ -44,12 +44,9 @@ import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -//~--- JDK imports ------------------------------------------------------------ +import static sonia.scm.repository.GitUtil.getCommit; +import static sonia.scm.repository.GitUtil.getCommitTime; -/** - * - * @author Sebastian Sdorra - */ public class GitBranchesCommand extends AbstractGitCommand implements BranchesCommand { private static final Logger LOG = LoggerFactory.getLogger(GitBranchesCommand.class); @@ -60,23 +57,22 @@ public class GitBranchesCommand extends AbstractGitCommand implements BranchesCo super(context); } - //~--- get methods ---------------------------------------------------------- - @Override public List getBranches() throws IOException { Git git = createGit(); String defaultBranchName = determineDefaultBranchName(git); - try { + Repository repository = git.getRepository(); + try (RevWalk refWalk = new RevWalk(repository)) { return git .branchList() .call() .stream() - .map(ref -> createBranchObject(defaultBranchName, ref)) + .map(ref -> createBranchObject(repository, refWalk, defaultBranchName, ref)) .collect(Collectors.toList()); } catch (GitAPIException ex) { - throw new InternalRepositoryException(repository, "could not read branches", ex); + throw new InternalRepositoryException(this.repository, "could not read branches", ex); } } @@ -86,21 +82,31 @@ public class GitBranchesCommand extends AbstractGitCommand implements BranchesCo } @Nullable - private Branch createBranchObject(String defaultBranchName, Ref ref) { + private Branch createBranchObject(Repository repository, RevWalk refWalk, String defaultBranchName, Ref ref) { String branchName = GitUtil.getBranch(ref); if (branchName == null) { LOG.warn("could not determine branch name for branch name {} at revision {}", ref.getName(), ref.getObjectId()); return null; } else { + Long lastCommitDate = getCommitDate(repository, refWalk, branchName, ref); if (branchName.equals(defaultBranchName)) { - return Branch.defaultBranch(branchName, GitUtil.getId(ref.getObjectId())); + return Branch.defaultBranch(branchName, GitUtil.getId(ref.getObjectId()), lastCommitDate); } else { - return Branch.normalBranch(branchName, GitUtil.getId(ref.getObjectId())); + return Branch.normalBranch(branchName, GitUtil.getId(ref.getObjectId()), lastCommitDate); } } } + private Long getCommitDate(Repository repository, RevWalk refWalk, String branchName, Ref ref) { + try { + return getCommitTime(getCommit(repository, refWalk, ref)); + } catch (IOException e) { + LOG.info("failed to read commit date of branch {} with revision {}", branchName, ref.getName()); + return null; + } + } + private String determineDefaultBranchName(Git git) { String defaultBranchName = context.getConfig().getDefaultBranch(); if (Strings.isNullOrEmpty(defaultBranchName)) { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchesCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchesCommandTest.java index 967226012a..fddf386d92 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchesCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitBranchesCommandTest.java @@ -24,117 +24,26 @@ package sonia.scm.repository.spi; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.ListBranchCommand; -import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.Ref; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; +import org.junit.Test; import sonia.scm.repository.Branch; -import sonia.scm.repository.GitRepositoryConfig; import java.io.IOException; import java.util.List; -import java.util.Optional; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Optional.of; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -@ExtendWith(MockitoExtension.class) -class GitBranchesCommandTest { - - @Mock - GitContext context; - @Mock - Git git; - @Mock - ListBranchCommand listBranchCommand; - @Mock - GitRepositoryConfig gitRepositoryConfig; - - GitBranchesCommand branchesCommand; - private Ref master; - - @BeforeEach - void initContext() { - when(context.getConfig()).thenReturn(gitRepositoryConfig); - } - - @BeforeEach - void initCommand() { - master = createRef("master", "0000"); - branchesCommand = new GitBranchesCommand(context) { - @Override - Git createGit() { - return git; - } - - @Override - Optional getRepositoryHeadRef(Git git) { - return of(master); - } - }; - when(git.branchList()).thenReturn(listBranchCommand); - } +public class GitBranchesCommandTest extends AbstractGitCommandTestBase { @Test - void shouldCreateEmptyListWithoutBranches() throws IOException, GitAPIException { - when(listBranchCommand.call()).thenReturn(emptyList()); + public void shouldReadBranches() throws IOException { + GitBranchesCommand branchesCommand = new GitBranchesCommand(createContext()); List branches = branchesCommand.getBranches(); - assertThat(branches).isEmpty(); - } - - @Test - void shouldMapNormalBranch() throws IOException, GitAPIException { - Ref branch = createRef("branch", "1337"); - when(listBranchCommand.call()).thenReturn(asList(branch)); - - List branches = branchesCommand.getBranches(); - - assertThat(branches).containsExactly(Branch.normalBranch("branch", "1337")); - } - - @Test - void shouldMarkMasterBranchWithMasterFromConfig() throws IOException, GitAPIException { - Ref branch = createRef("branch", "1337"); - when(listBranchCommand.call()).thenReturn(asList(branch)); - when(gitRepositoryConfig.getDefaultBranch()).thenReturn("branch"); - - List branches = branchesCommand.getBranches(); - - assertThat(branches).containsExactlyInAnyOrder(Branch.defaultBranch("branch", "1337")); - } - - @Test - void shouldMarkMasterBranchWithMasterFromHead() throws IOException, GitAPIException { - Ref branch = createRef("branch", "1337"); - when(listBranchCommand.call()).thenReturn(asList(branch, master)); - - List branches = branchesCommand.getBranches(); - - assertThat(branches).containsExactlyInAnyOrder( - Branch.normalBranch("branch", "1337"), - Branch.defaultBranch("master", "0000") + assertThat(branches).contains( + Branch.defaultBranch("master", "fcd0ef1831e4002ac43ea539f4094334c79ea9ec", 1339428655000L), + Branch.normalBranch("mergeable", "91b99de908fcd04772798a31c308a64aea1a5523", 1541586052000L), + Branch.normalBranch("rename", "383b954b27e052db6880d57f1c860dc208795247", 1589203061000L) ); } - - private Ref createRef(String branchName, String revision) { - Ref ref = mock(Ref.class); - lenient().when(ref.getName()).thenReturn("refs/heads/" + branchName); - ObjectId objectId = mock(ObjectId.class); - lenient().when(objectId.name()).thenReturn(revision); - lenient().when(ref.getObjectId()).thenReturn(objectId); - return ref; - } }