diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java index d1ae422f..710c0874 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepository.java @@ -323,7 +323,8 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository } /** - * Clones the remote repository and then opens a connection to it. + * Clones the remote repository and then opens a connection to it. Checks out to the + * defaultLabel if specified. * @throws GitAPIException when cloning fails * @throws IOException when repo opening fails */ @@ -335,6 +336,23 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository git.close(); } git = openGitRepository(); + + // Check if git points to valid repository and default label is not empty or + // null. + if (null != git && git.getRepository() != null + && !StringUtils.isEmpty(getDefaultLabel())) { + // Checkout the default branch set for repo in git. This may not always be + // master. It depends on the + // admin and organization settings. + String defaultBranchInGit = git.getRepository().getBranch(); + // If default branch is not empty and NOT equal to defaultLabel, then + // checkout the branch/tag/commit-id. + if (!StringUtils.isEmpty(defaultBranchInGit) + && !getDefaultLabel().equalsIgnoreCase(defaultBranchInGit)) { + checkout(git, getDefaultLabel()); + } + } + if (git != null) { git.close(); } diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java index 83752a79..08673c3f 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/environment/JGitEnvironmentRepositoryTests.java @@ -1059,6 +1059,128 @@ public class JGitEnvironmentRepositoryTests { verify(deleteBranchCommand).call(); } + /** + * Test case to set if the default-label is checked out. + * @throws Exception should throw any runtime exception. + */ + @Test + public void afterPropertiesSet_CloneOnStartTrue_DefaultLabelSet_CloneAndCheckoutCalled() + throws Exception { + final String LABEL_TO_CHECKOUT = "release"; + // Set the default branch of repository as master + Repository mockRepository = mock(Repository.class); + when(mockRepository.getBranch()).thenReturn("master"); + + Git mockGit = mock(Git.class); + when(mockGit.getRepository()).thenReturn(mockRepository); + + // Mock the clone command + CloneCommand mockCloneCommand = mock(CloneCommand.class); + when(mockCloneCommand.setURI(anyString())).thenReturn(mockCloneCommand); + when(mockCloneCommand.setDirectory(any(File.class))).thenReturn(mockCloneCommand); + + // Mocking the commands to checkout to label. + ListBranchCommand mockListBranchCommand = mock(ListBranchCommand.class); + CheckoutCommand mockCheckoutCommand = mock(CheckoutCommand.class); + + // Return the mocked checkout and ListBranchCommand. + when(mockGit.checkout()).thenReturn(mockCheckoutCommand); + when(mockGit.branchList()).thenReturn(mockListBranchCommand); + + // Add 2 branches on mock repo {master, release} + List repositoryRefsList = new ArrayList<>(); + + // Mock master branch + Ref mockMasterRef = mock(Ref.class); + repositoryRefsList.add(mockMasterRef); + when(mockMasterRef.getName()).thenReturn("/master"); + + // Mock release branch. + Ref mockReleaseRef = mock(Ref.class); + repositoryRefsList.add(mockReleaseRef); + when(mockReleaseRef.getName()).thenReturn("/release"); + + // Mock calls on list and checkout commands + when(mockListBranchCommand.call()).thenReturn(repositoryRefsList); + when(mockCheckoutCommand.call()).thenReturn(mockReleaseRef); + + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository( + this.environment, new JGitEnvironmentProperties()); + envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); + envRepository.setUri("http://somegitserver/somegitrepo"); + envRepository.setCloneOnStart(true); + + // Set the label to checkout. should be different from master + envRepository.setDefaultLabel(LABEL_TO_CHECKOUT); + envRepository.afterPropertiesSet(); + verify(mockCloneCommand, times(1)).call(); + verify(mockCheckoutCommand, times(1)).call(); + verify(mockListBranchCommand, times(2)).call(); + verify(mockCheckoutCommand, times(1)).setName(anyString()); + } + + /** + * Test case to validate that check out is not called when the default branch for repo + * is same as default label. + * @throws Exception should throw any runtime exception. + */ + @Test + public void afterPropertiesSet_CloneOnStartTrue_DefaultLabelSameAsDefaultBranch_CheckoutNotCalled() + throws Exception { + final String LABEL_TO_CHECKOUT = "master"; + // Set the default branch of repository as master + Repository mockRepository = mock(Repository.class); + when(mockRepository.getBranch()).thenReturn("master"); + + Git mockGit = mock(Git.class); + when(mockGit.getRepository()).thenReturn(mockRepository); + + // Mock the clone command + CloneCommand mockCloneCommand = mock(CloneCommand.class); + when(mockCloneCommand.setURI(anyString())).thenReturn(mockCloneCommand); + when(mockCloneCommand.setDirectory(any(File.class))).thenReturn(mockCloneCommand); + + // Mocking the commands to checkout to label. + ListBranchCommand mockListBranchCommand = mock(ListBranchCommand.class); + CheckoutCommand mockCheckoutCommand = mock(CheckoutCommand.class); + + // Return the mocked checkout and ListBranchCommand. + when(mockGit.checkout()).thenReturn(mockCheckoutCommand); + when(mockGit.branchList()).thenReturn(mockListBranchCommand); + + // Add 2 branches on mock repo {master, release} + List repositoryRefsList = new ArrayList<>(); + + // Mock master branch + Ref mockMasterRef = mock(Ref.class); + repositoryRefsList.add(mockMasterRef); + when(mockMasterRef.getName()).thenReturn("/master"); + + // Mock release branch. + Ref mockReleaseRef = mock(Ref.class); + repositoryRefsList.add(mockReleaseRef); + when(mockReleaseRef.getName()).thenReturn("/release"); + + // Mock calls on list and checkout commands + when(mockListBranchCommand.call()).thenReturn(repositoryRefsList); + when(mockCheckoutCommand.call()).thenReturn(mockReleaseRef); + + JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository( + this.environment, new JGitEnvironmentProperties()); + envRepository.setGitFactory(new MockGitFactory(mockGit, mockCloneCommand)); + envRepository.setUri("http://somegitserver/somegitrepo"); + envRepository.setCloneOnStart(true); + + // Set the label to checkout. should be different from master + envRepository.setDefaultLabel(LABEL_TO_CHECKOUT); + envRepository.afterPropertiesSet(); + verify(mockCloneCommand, times(1)).call(); + // Checkout/List Branch/Checkout setName should not be called + verify(mockCheckoutCommand, times(0)).call(); + verify(mockListBranchCommand, times(0)).call(); + verify(mockCheckoutCommand, times(0)).setName(anyString()); + } + class MockCloneCommand extends CloneCommand { private Git mockGit;