11package org .scm4j .vcs ;
22
3+ import java .io .ByteArrayOutputStream ;
4+ import java .io .File ;
5+ import java .io .FileWriter ;
6+ import java .io .IOException ;
7+ import java .net .Authenticator ;
8+ import java .net .InetSocketAddress ;
9+ import java .net .PasswordAuthentication ;
10+ import java .net .Proxy ;
11+ import java .net .Proxy .Type ;
12+ import java .net .ProxySelector ;
13+ import java .net .SocketAddress ;
14+ import java .net .URI ;
15+ import java .nio .charset .StandardCharsets ;
16+ import java .util .ArrayList ;
17+ import java .util .Collections ;
18+ import java .util .Comparator ;
19+ import java .util .Date ;
20+ import java .util .HashSet ;
21+ import java .util .List ;
22+ import java .util .Set ;
23+
324import org .apache .commons .io .FileUtils ;
425import org .apache .commons .io .IOUtils ;
5- import org .eclipse .jgit .api .* ;
26+ import org .eclipse .jgit .api .CheckoutCommand ;
627import org .eclipse .jgit .api .CreateBranchCommand .SetupUpstreamMode ;
28+ import org .eclipse .jgit .api .Git ;
729import org .eclipse .jgit .api .ListBranchCommand .ListMode ;
30+ import org .eclipse .jgit .api .LogCommand ;
31+ import org .eclipse .jgit .api .MergeResult ;
32+ import org .eclipse .jgit .api .PushCommand ;
833import org .eclipse .jgit .api .ResetCommand .ResetType ;
934import org .eclipse .jgit .api .errors .GitAPIException ;
1035import org .eclipse .jgit .api .errors .RefAlreadyExistsException ;
1136import org .eclipse .jgit .diff .DiffEntry ;
1237import org .eclipse .jgit .diff .DiffEntry .ChangeType ;
1338import org .eclipse .jgit .diff .DiffEntry .Side ;
1439import org .eclipse .jgit .diff .DiffFormatter ;
15- import org .eclipse .jgit .errors .IncorrectObjectTypeException ;
16- import org .eclipse .jgit .lib .*;
40+ import org .eclipse .jgit .lib .Constants ;
41+ import org .eclipse .jgit .lib .ObjectId ;
42+ import org .eclipse .jgit .lib .ObjectReader ;
43+ import org .eclipse .jgit .lib .Ref ;
44+ import org .eclipse .jgit .lib .Repository ;
1745import org .eclipse .jgit .revwalk .RevCommit ;
46+ import org .eclipse .jgit .revwalk .RevObject ;
1847import org .eclipse .jgit .revwalk .RevSort ;
1948import org .eclipse .jgit .revwalk .RevTag ;
2049import org .eclipse .jgit .revwalk .RevWalk ;
2352import org .eclipse .jgit .transport .RefSpec ;
2453import org .eclipse .jgit .transport .UsernamePasswordCredentialsProvider ;
2554import org .eclipse .jgit .treewalk .CanonicalTreeParser ;
26- import org .scm4j .vcs .api .*;
55+ import org .scm4j .vcs .api .IVCS ;
56+ import org .scm4j .vcs .api .VCSChangeType ;
57+ import org .scm4j .vcs .api .VCSCommit ;
58+ import org .scm4j .vcs .api .VCSDiffEntry ;
59+ import org .scm4j .vcs .api .VCSMergeResult ;
60+ import org .scm4j .vcs .api .VCSTag ;
61+ import org .scm4j .vcs .api .WalkDirection ;
2762import org .scm4j .vcs .api .exceptions .EVCSBranchExists ;
2863import org .scm4j .vcs .api .exceptions .EVCSException ;
2964import org .scm4j .vcs .api .exceptions .EVCSFileNotFound ;
3267import org .scm4j .vcs .api .workingcopy .IVCSRepositoryWorkspace ;
3368import org .scm4j .vcs .api .workingcopy .IVCSWorkspace ;
3469
35- import java .io .ByteArrayOutputStream ;
36- import java .io .File ;
37- import java .io .FileWriter ;
38- import java .io .IOException ;
39- import java .net .*;
40- import java .net .Proxy .Type ;
41- import java .nio .charset .StandardCharsets ;
42- import java .util .*;
43-
4470public class GitVCS implements IVCS {
4571
4672 public static final String GIT_VCS_TYPE_STRING = "git" ;
@@ -110,7 +136,7 @@ public void createBranch(String srcBranchName, String newBranchName, String comm
110136 Git git = getLocalGit (wc );
111137 Repository gitRepo = git .getRepository ()) {
112138
113- checkout (git , gitRepo , srcBranchName );
139+ checkout (git , gitRepo , srcBranchName , null );
114140
115141 git
116142 .branchCreate ()
@@ -137,7 +163,7 @@ public void deleteBranch(String branchName, String commitMessage) {
137163 Git git = getLocalGit (wc );
138164 Repository gitRepo = git .getRepository ()) {
139165
140- checkout (git , gitRepo , MASTER_BRANCH_NAME );
166+ checkout (git , gitRepo , MASTER_BRANCH_NAME , null );
141167
142168 git
143169 .branchDelete ()
@@ -174,7 +200,7 @@ public VCSMergeResult merge(String srcBranchName, String dstBranchName, String c
174200 Git git = getLocalGit (wc );
175201 Repository gitRepo = git .getRepository ()) {
176202
177- checkout (git , gitRepo , dstBranchName );
203+ checkout (git , gitRepo , dstBranchName , null );
178204
179205 MergeResult mr = git
180206 .merge ()
@@ -263,7 +289,7 @@ private File getFileFromRepo(String branchName, String fileRelativePath) {
263289 Git git = getLocalGit (wc );
264290 Repository gitRepo = git .getRepository ()) {
265291
266- checkout (git , gitRepo , branchName );
292+ checkout (git , gitRepo , branchName , null );
267293
268294 return new File (wc .getFolder (), fileRelativePath );
269295 } catch (GitAPIException e ) {
@@ -292,7 +318,7 @@ public VCSCommit setFileContent(String branchName, String filePath, String conte
292318 Git git = getLocalGit (wc );
293319 Repository gitRepo = git .getRepository ()) {
294320
295- checkout (git , gitRepo , branchName );
321+ checkout (git , gitRepo , branchName , null );
296322
297323 File file = new File (wc .getFolder (), filePath );
298324 if (!file .exists ()) {
@@ -325,19 +351,25 @@ public VCSCommit setFileContent(String branchName, String filePath, String conte
325351 }
326352 }
327353
328- void checkout (Git git , Repository gitRepo , String branchName ) throws Exception {
354+ void checkout (Git git , Repository gitRepo , String branchName , String revision ) throws Exception {
329355 String bn = getRealBranchName (branchName );
330- git
331- .pull ()
332- .setCredentialsProvider (credentials )
333- .call ();
334- git
335- .checkout ()
336- .setStartPoint ("origin/" + bn )
337- .setCreateBranch (gitRepo .exactRef ("refs/heads/" + bn ) == null )
338- .setUpstreamMode (SetupUpstreamMode .TRACK )
339- .setName (bn )
340- .call ();
356+ CheckoutCommand cmd = git .checkout ();
357+ if (revision == null ) {
358+ cmd
359+ .setStartPoint ("origin/" + bn )
360+ .setCreateBranch (gitRepo .exactRef ("refs/heads/" + bn ) == null )
361+ .setUpstreamMode (SetupUpstreamMode .TRACK )
362+ .setName (bn )
363+ .call ();
364+ } else {
365+ try (RevWalk walk = new RevWalk (gitRepo )) {
366+ RevCommit commit = walk .parseCommit (RevCommit .fromString (revision ));
367+ // note: entering "detached HEAD" state here
368+ cmd
369+ .setName (commit .getName ())
370+ .call ();
371+ }
372+ }
341373 }
342374
343375 @ Override
@@ -361,7 +393,7 @@ public List<VCSDiffEntry> getBranchesDiff(String srcBranchName, String dstBranch
361393
362394 ObjectReader reader = gitRepo .newObjectReader ();
363395
364- checkout (git , gitRepo , dstBranchName );
396+ checkout (git , gitRepo , dstBranchName , null );
365397
366398 git
367399 .merge ()
@@ -403,7 +435,7 @@ public Set<String> getBranches(String path) {
403435 try (IVCSLockedWorkingCopy wc = repo .getVCSLockedWorkingCopy ();
404436 Git git = getLocalGit (wc );
405437 Repository gitRepo = git .getRepository ()) {
406- checkout (git , gitRepo , MASTER_BRANCH_NAME );
438+ checkout (git , gitRepo , MASTER_BRANCH_NAME , null );
407439 List <Ref > refs = git
408440 .branchList ()
409441 .setListMode (ListMode .REMOTE )
@@ -460,7 +492,7 @@ public VCSCommit removeFile(String branchName, String filePath, String commitMes
460492 Git git = getLocalGit (wc );
461493 Repository gitRepo = git .getRepository ()) {
462494
463- checkout (git , gitRepo , branchName );
495+ checkout (git , gitRepo , branchName , null );
464496
465497 git
466498 .rm ()
@@ -492,7 +524,7 @@ public List<VCSCommit> getCommitsRange(String branchName, String afterCommitId,
492524 Git git = getLocalGit (wc );
493525 Repository gitRepo = git .getRepository ()) {
494526
495- checkout (git , gitRepo , branchName );
527+ checkout (git , gitRepo , branchName , null );
496528
497529 String bn = getRealBranchName (branchName );
498530
@@ -548,7 +580,7 @@ public List<VCSCommit> getCommitsRange(String branchName, String startFromCommit
548580 Git git = getLocalGit (wc );
549581 Repository gitRepo = git .getRepository ()) {
550582
551- checkout (git , gitRepo , branchName );
583+ checkout (git , gitRepo , branchName , null );
552584
553585 String bn = getRealBranchName (branchName );
554586
@@ -635,20 +667,22 @@ public Boolean fileExists(String branchName, String filePath) {
635667 }
636668
637669 @ Override
638- public VCSTag createTag (String branchName , String tagName , String tagMessage ) throws EVCSTagExists {
670+ public VCSTag createTag (String branchName , String tagName , String tagMessage , String revisionToTag ) throws EVCSTagExists {
639671 try (IVCSLockedWorkingCopy wc = repo .getVCSLockedWorkingCopy ();
640672 Git git = getLocalGit (wc );
641673 Repository gitRepo = git .getRepository ();
642674 RevWalk rw = new RevWalk (gitRepo )) {
643675
644- checkout (git , gitRepo , branchName );
676+ checkout (git , gitRepo , branchName , null );
677+
678+ RevCommit commitToTag = revisionToTag == null ? null : rw .parseCommit (ObjectId .fromString (revisionToTag ));
645679
646680 Ref ref = git
647681 .tag ()
648682 .setAnnotated (true )
649683 .setMessage (tagMessage )
650684 .setName (tagName )
651- .setObjectId (null ) //rw.gparseCommit(ObjectId.fromString(commitIdToTag)))
685+ .setObjectId (commitToTag )
652686 .call ();
653687
654688 push (git , new RefSpec (ref .getName ()));
@@ -675,20 +709,19 @@ public List<VCSTag> getTags() {
675709
676710 List <Ref > tagRefs = getTagRefs ();
677711 List <VCSTag > res = new ArrayList <>();
678- RevTag revTag ;
679712 RevCommit revCommit ;
680713 for (Ref ref : tagRefs ) {
681714 ObjectId relatedCommitObjectId = ref .getPeeledObjectId () == null ? ref .getObjectId () : ref .getPeeledObjectId ();
682715 revCommit = rw .parseCommit (relatedCommitObjectId );
683716 VCSCommit relatedCommit = getVCSCommit (revCommit );
717+ RevObject revObject = rw .parseAny (ref .getObjectId ());
684718 VCSTag tag ;
685- try {
686- revTag = rw . parseTag ( ref . getObjectId ()) ;
719+ if ( revObject instanceof RevTag ) {
720+ RevTag revTag = ( RevTag ) revObject ;
687721 tag = new VCSTag (revTag .getTagName (), revTag .getFullMessage (), revTag .getTaggerIdent ().getName (), relatedCommit );
688- } catch (IncorrectObjectTypeException e ) {
689- // tag is unannonated
722+ } else {
690723 tag = new VCSTag (ref .getName ().replace ("refs/tags/" , "" ), null , null , relatedCommit );
691- }
724+ }
692725 res .add (tag );
693726 }
694727 return res ;
@@ -702,8 +735,8 @@ List<Ref> getTagRefs() throws Exception {
702735 Git git = getLocalGit (wc );
703736 Repository gitRepo = git .getRepository ()) {
704737
705- checkout (git , gitRepo , MASTER_BRANCH_NAME );
706-
738+ checkout (git , gitRepo , MASTER_BRANCH_NAME , null );
739+
707740 List <Ref > refs = git
708741 .tagList ()
709742 .call ();
@@ -759,11 +792,11 @@ public int compare(Ref o1, Ref o2) {
759792 @ Override
760793 public void removeTag (String tagName ) {
761794 try (IVCSLockedWorkingCopy wc = repo .getVCSLockedWorkingCopy ();
762- Git git = getLocalGit (wc );
763- Repository gitRepo = git .getRepository ();
764- RevWalk rw = new RevWalk (gitRepo )) {
795+ Git git = getLocalGit (wc );
796+ Repository gitRepo = git .getRepository ();
797+ RevWalk rw = new RevWalk (gitRepo )) {
765798
766- checkout (git , gitRepo , MASTER_BRANCH_NAME );
799+ checkout (git , gitRepo , MASTER_BRANCH_NAME , null );
767800
768801 git
769802 .tagDelete ()
@@ -780,16 +813,44 @@ public void removeTag(String tagName) {
780813 }
781814
782815 @ Override
783- public void checkout (String branchName , String targetPath ) {
816+ public void checkout (String branchName , String targetPath , String revision ) {
784817 try (Git git = getLocalGit (targetPath );
785818 Repository gitRepo = git .getRepository ()) {
786819
787- checkout (git , gitRepo , branchName );
820+ checkout (git , gitRepo , branchName , revision );
788821
789822 } catch (GitAPIException e ) {
790823 throw new EVCSException (e );
791824 } catch (Exception e ) {
792825 throw new RuntimeException (e );
793826 }
794827 }
828+
829+ @ Override
830+ public Boolean isRevisionTagged (String revision ) {
831+ try (IVCSLockedWorkingCopy wc = repo .getVCSLockedWorkingCopy ();
832+ Git git = getLocalGit (wc );
833+ Repository gitRepo = git .getRepository ();
834+ RevWalk rw = new RevWalk (gitRepo )) {
835+ checkout (git , gitRepo , MASTER_BRANCH_NAME , null );
836+ List <Ref > tagRefs = getTagRefs ();
837+ for (Ref ref : tagRefs ) {
838+ RevObject revObject = rw .parseAny (ref .getObjectId ());
839+ if (revObject instanceof RevTag ) {
840+ if (((RevTag ) revObject ).getObject ().getName ().equals (revision )) {
841+ return true ;
842+ }
843+ } else {
844+ if (revObject .getName ().equals (revision )) {
845+ return true ;
846+ }
847+ }
848+ }
849+ return false ;
850+ } catch (GitAPIException e ) {
851+ throw new EVCSException (e );
852+ } catch (Exception e ) {
853+ throw new RuntimeException (e );
854+ }
855+ }
795856}
0 commit comments