Skip to content

Commit e1fa697

Browse files
committed
Do prune branches and tags to remove local which does not exist on remote
1 parent a4299c3 commit e1fa697

File tree

2 files changed

+104
-62
lines changed

2 files changed

+104
-62
lines changed

src/main/java/org/scm4j/vcs/GitVCS.java

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,17 @@
55
import org.eclipse.jgit.api.*;
66
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
77
import org.eclipse.jgit.api.ResetCommand.ResetType;
8+
import org.eclipse.jgit.api.errors.CanceledException;
9+
import org.eclipse.jgit.api.errors.DetachedHeadException;
810
import org.eclipse.jgit.api.errors.GitAPIException;
11+
import org.eclipse.jgit.api.errors.InvalidConfigurationException;
12+
import org.eclipse.jgit.api.errors.InvalidRemoteException;
13+
import org.eclipse.jgit.api.errors.NoHeadException;
914
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
15+
import org.eclipse.jgit.api.errors.RefNotAdvertisedException;
16+
import org.eclipse.jgit.api.errors.RefNotFoundException;
17+
import org.eclipse.jgit.api.errors.TransportException;
18+
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
1019
import org.eclipse.jgit.diff.DiffEntry;
1120
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
1221
import org.eclipse.jgit.diff.DiffEntry.Side;
@@ -132,7 +141,7 @@ public void createBranch(String srcBranchName, String newBranchName, String comm
132141
Repository gitRepo = git.getRepository()) {
133142

134143
checkout(git, gitRepo, srcBranchName, null);
135-
144+
136145
git
137146
.branchCreate()
138147
.setUpstreamMode(SetupUpstreamMode.TRACK)
@@ -176,7 +185,7 @@ public void deleteBranch(String branchName, String commitMessage) {
176185
}
177186
}
178187

179-
private void push(Git git, RefSpec refSpec) throws GitAPIException {
188+
void push(Git git, RefSpec refSpec) throws GitAPIException {
180189
PushCommand cmd = git
181190
.push();
182191
if (refSpec != null) {
@@ -285,18 +294,8 @@ public String getFileContent(String branchName, String fileRelativePath, String
285294
Repository gitRepo = git.getRepository();
286295
RevWalk revWalk = new RevWalk(gitRepo);
287296
TreeWalk treeWalk = new TreeWalk(gitRepo)) {
288-
289-
git
290-
.pull()
291-
.setCredentialsProvider(credentials)
292-
.call();
293-
294-
// if executed first then version is considered as modified. So have uncommited change: 19.5-SNAPSHOT -> 18.5-SNAPSHOT
295-
git
296-
.fetch()
297-
.setRefSpecs(new RefSpec("+refs/heads/*:refs/heads/*"))
298-
.setCredentialsProvider(credentials)
299-
.call();
297+
298+
pullAndFetch(git);
300299

301300
ObjectId revisionCommitId = gitRepo.resolve(revision == null ? REFS_HEADS + getRealBranchName(branchName) : revision);
302301
if (revision == null && revisionCommitId == null) {
@@ -388,10 +387,9 @@ public VCSCommit setFileContent(String branchName, String filePath, String conte
388387
private void checkout(Git git, Repository gitRepo, String branchName, String revision) throws Exception {
389388
String bn = getRealBranchName(branchName);
390389
CheckoutCommand cmd = git.checkout();
391-
git
392-
.pull()
393-
.setCredentialsProvider(credentials)
394-
.call();
390+
391+
pullAndFetch(git);
392+
395393
if (revision == null) {
396394
cmd
397395
.setStartPoint("origin/" + bn)
@@ -411,6 +409,27 @@ private void checkout(Git git, Repository gitRepo, String branchName, String rev
411409
}
412410
}
413411

412+
private void pullAndFetch(Git git) throws GitAPIException, WrongRepositoryStateException,
413+
InvalidConfigurationException, DetachedHeadException, InvalidRemoteException, CanceledException,
414+
RefNotFoundException, RefNotAdvertisedException, NoHeadException, TransportException {
415+
git
416+
.pull()
417+
.setCredentialsProvider(credentials)
418+
.call();
419+
420+
// remove local branches and tags which are not exists on remote
421+
// See https://github.com/scm4j/scm4j-releaser/issues/59
422+
// if executed first then version is considered as modified. So have uncommited change: 19.5-SNAPSHOT -> 18.5-SNAPSHOT
423+
git
424+
.fetch()
425+
.setRefSpecs(
426+
new RefSpec("+refs/heads/*:refs/heads/*"),
427+
new RefSpec("+refs/tags/*:refs/tags/*"))
428+
.setRemoveDeletedRefs(true)
429+
.setCredentialsProvider(credentials)
430+
.call();
431+
}
432+
414433
@Override
415434
public List<VCSDiffEntry> getBranchesDiff(String srcBranchName, String dstBranchName) {
416435
try (IVCSLockedWorkingCopy wc = repo.getVCSLockedWorkingCopy();
@@ -469,18 +488,9 @@ public Set<String> getBranches(String path) {
469488
try (IVCSLockedWorkingCopy wc = repo.getVCSLockedWorkingCopy();
470489
Git git = getLocalGit(wc);
471490
Repository gitRepo = git.getRepository()) {
472-
473-
git
474-
.pull()
475-
.setCredentialsProvider(credentials)
476-
.call();
477-
git
478-
.fetch()
479-
.setRefSpecs(new RefSpec("+refs/heads/*:refs/heads/*"))
480-
.setRemoveDeletedRefs(true)
481-
.setCredentialsProvider(credentials)
482-
.call();
483-
491+
492+
pullAndFetch(git);
493+
484494
Collection<Ref> refs = gitRepo.getRefDatabase().getRefs(REFS_REMOTES_ORIGIN).values();
485495
Set<String> res = new HashSet<>();
486496
String bn;
@@ -721,7 +731,7 @@ public VCSTag createTag(String branchName, String tagName, String tagMessage, St
721731
Repository gitRepo = git.getRepository();
722732
RevWalk rw = new RevWalk(gitRepo)) {
723733

724-
updateLocalTags(git);
734+
pullAndFetch(git);
725735

726736
checkout(git, gitRepo, branchName, null);
727737

@@ -750,32 +760,14 @@ public VCSTag createTag(String branchName, String tagName, String tagMessage, St
750760
}
751761
}
752762

753-
private void updateLocalTags(Git git) throws Exception {
754-
// need to remove tags from local repo which are removed in origin
755-
756-
git
757-
.pull()
758-
.setCredentialsProvider(credentials)
759-
.call();
760-
git
761-
.fetch()
762-
.setRefSpecs(new RefSpec("+refs/tags/*:refs/tags/*"))
763-
.setRemoveDeletedRefs(true)
764-
.setCredentialsProvider(credentials)
765-
.call();
766-
767-
}
768-
769-
770-
771763
@Override
772764
public List<VCSTag> getTags() {
773765
try (IVCSLockedWorkingCopy wc = repo.getVCSLockedWorkingCopy();
774766
Git git = getLocalGit(wc);
775767
Repository gitRepo = git.getRepository();
776768
RevWalk rw = new RevWalk(gitRepo)) {
777769

778-
updateLocalTags(git);
770+
pullAndFetch(git);
779771
Collection<Ref> tagRefs = gitRepo.getTags().values();
780772
List<VCSTag> res = new ArrayList<>();
781773
RevCommit revCommit;
@@ -807,7 +799,7 @@ public void removeTag(String tagName) {
807799
Repository gitRepo = git.getRepository();
808800
RevWalk rw = new RevWalk(gitRepo)) {
809801

810-
updateLocalTags(git);
802+
pullAndFetch(git);
811803

812804
git
813805
.tagDelete()
@@ -844,7 +836,7 @@ public List<VCSTag> getTagsOnRevision(String revision) {
844836
Repository gitRepo = git.getRepository();
845837
RevWalk rw = new RevWalk(gitRepo)) {
846838

847-
updateLocalTags(git);
839+
pullAndFetch(git);
848840

849841
List<VCSTag> res = new ArrayList<>();
850842

src/test/java/org/scm4j/vcs/GitVCSTest.java

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
11
package org.scm4j.vcs;
22

3+
import static org.junit.Assert.assertEquals;
4+
import static org.junit.Assert.assertNotNull;
5+
import static org.junit.Assert.assertNull;
6+
import static org.junit.Assert.assertTrue;
7+
import static org.junit.Assert.fail;
8+
9+
import java.io.File;
10+
import java.io.IOException;
11+
import java.lang.reflect.InvocationTargetException;
12+
import java.lang.reflect.Method;
13+
import java.net.Authenticator;
14+
import java.net.InetAddress;
15+
import java.net.InetSocketAddress;
16+
import java.net.PasswordAuthentication;
17+
import java.net.Proxy;
18+
import java.net.ProxySelector;
19+
import java.net.SocketAddress;
20+
import java.net.URI;
21+
import java.net.URISyntaxException;
22+
import java.util.Arrays;
23+
import java.util.List;
24+
325
import org.apache.commons.io.FileUtils;
426
import org.apache.commons.lang3.ArrayUtils;
527
import org.eclipse.jgit.api.Git;
628
import org.eclipse.jgit.api.errors.GitAPIException;
729
import org.eclipse.jgit.diff.DiffEntry;
830
import org.eclipse.jgit.lib.Repository;
931
import org.eclipse.jgit.transport.CredentialItem;
32+
import org.eclipse.jgit.transport.RefSpec;
1033
import org.junit.After;
1134
import org.junit.Test;
1235
import org.mockito.Mockito;
@@ -22,16 +45,6 @@
2245
import org.scm4j.vcs.api.workingcopy.IVCSWorkspace;
2346
import org.scm4j.vcs.api.workingcopy.VCSWorkspace;
2447

25-
import java.io.File;
26-
import java.io.IOException;
27-
import java.lang.reflect.InvocationTargetException;
28-
import java.lang.reflect.Method;
29-
import java.net.*;
30-
import java.util.Arrays;
31-
import java.util.List;
32-
33-
import static org.junit.Assert.*;
34-
3548
public class GitVCSTest extends VCSAbstractTest {
3649

3750
private Repository localGitRepo;
@@ -295,5 +308,42 @@ public void testGetTagsOnRevisionUnannotated() throws Exception {
295308
assertTrue(vcs.getTagsOnRevision(c3.getRevision()).containsAll(Arrays.asList(
296309
tag3)));
297310
}
311+
312+
@Test
313+
public void testPruneOnBranchCreate() throws Exception {
314+
// create a local branch, push failed
315+
RuntimeException eCommon = new RuntimeException("test common exception");
316+
Mockito.doThrow(eCommon).when(git).push(Mockito.any(Git.class), Mockito.any(RefSpec.class));
317+
try {
318+
vcs.createBranch(null, "branch", "branch created");
319+
fail();
320+
} catch (RuntimeException e) {
321+
}
322+
323+
Mockito.doCallRealMethod().when(git).push(Mockito.any(Git.class), Mockito.any(RefSpec.class));
324+
325+
// expect no EVCSBRanchExists exception
326+
vcs.createBranch(null, "branch", "branch created");
327+
assertTrue(vcs.getBranches("").contains("branch"));
328+
}
329+
330+
@Test
331+
public void testPruneOnTagCreate() throws Exception {
332+
// create a local tag, push failed
333+
RuntimeException eCommon = new RuntimeException("test common exception");
334+
Mockito.doThrow(eCommon).when(git).push(Mockito.any(Git.class), Mockito.any(RefSpec.class));
335+
336+
try {
337+
vcs.createTag(null, "tag", "tag desc", null);
338+
fail();
339+
} catch (RuntimeException e) {
340+
}
341+
342+
Mockito.doCallRealMethod().when(git).push(Mockito.any(Git.class), Mockito.any(RefSpec.class));
343+
344+
// expect no exceptions
345+
vcs.createTag(null, "tag", "tag desc", null);
346+
assertEquals("tag", vcs.getTags().get(0).getTagName());
347+
}
298348
}
299349

0 commit comments

Comments
 (0)