View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.releaser.util.github;
35  
36  import java.io.File;
37  import java.io.IOException;
38  import java.io.UnsupportedEncodingException;
39  import java.net.URLEncoder;
40  import java.text.MessageFormat;
41  import java.util.ArrayList;
42  import java.util.Collection;
43  import java.util.HashMap;
44  import java.util.Iterator;
45  import java.util.List;
46  import java.util.Map;
47  
48  import org.apache.commons.lang3.StringUtils;
49  import org.eclipse.jgit.api.CloneCommand;
50  import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
51  import org.eclipse.jgit.api.ListBranchCommand.ListMode;
52  import org.eclipse.jgit.api.Git;
53  import org.eclipse.jgit.api.MergeResult;
54  import org.eclipse.jgit.api.PullResult;
55  import org.eclipse.jgit.api.errors.CanceledException;
56  import org.eclipse.jgit.api.errors.CheckoutConflictException;
57  import org.eclipse.jgit.api.errors.DetachedHeadException;
58  import org.eclipse.jgit.api.errors.GitAPIException;
59  import org.eclipse.jgit.api.errors.InvalidConfigurationException;
60  import org.eclipse.jgit.api.errors.InvalidRefNameException;
61  import org.eclipse.jgit.api.errors.InvalidRemoteException;
62  import org.eclipse.jgit.api.errors.NoHeadException;
63  import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
64  import org.eclipse.jgit.api.errors.RefNotFoundException;
65  import org.eclipse.jgit.api.errors.TransportException;
66  import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
67  import org.eclipse.jgit.lib.Ref;
68  import org.eclipse.jgit.lib.Repository;
69  import org.eclipse.jgit.revwalk.RevCommit;
70  import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
71  import org.eclipse.jgit.transport.CredentialsProvider;
72  import org.eclipse.jgit.transport.RefSpec;
73  import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
74  
75  import fr.paris.lutece.plugins.releaser.util.CommandResult;
76  import fr.paris.lutece.plugins.releaser.util.ConstanteUtils;
77  import fr.paris.lutece.plugins.releaser.util.MapperJsonUtil;
78  import fr.paris.lutece.plugins.releaser.util.ReleaserUtils;
79  import fr.paris.lutece.portal.service.util.AppLogService;
80  import fr.paris.lutece.portal.service.util.AppPropertiesService;
81  import fr.paris.lutece.util.httpaccess.HttpAccess;
82  import fr.paris.lutece.util.httpaccess.HttpAccessException;
83  import fr.paris.lutece.util.signrequest.BasicAuthorizationAuthenticator;
84  
85  // TODO: Auto-generated Javadoc
86  /**
87   * The Class GitUtils.
88   */
89  public class GitUtils
90  {
91  
92      /** The Constant MASTER_BRANCH. */
93      public static final String MASTER_BRANCH = "master";
94  
95      /** The Constant DEVELOP_BRANCH. */
96      public static final String DEFAULT_RELEASE_BRANCH = "develop";
97  
98      /** The Constant CONSTANTE_REF_TAG. */
99      private static final String CONSTANTE_REF_TAG = "refs/tags/";
100 
101     /**
102      * Clone repo.
103      *
104      * @param sClonePath
105      *            the s clone path
106      * @param sRepoURL
107      *            the s repo URL
108      * @param commandResult
109      *            the command result
110      * @param strGitHubUserLogin
111      *            the str git hub user login
112      * @param strUserName
113      *            the str user name
114      * @param strPassword
115      *            the str password
116      * @return the git
117      */
118     public static Git cloneRepo( String sClonePath, String sRepoURL, CommandResult commandResult, String strGitHubUserLogin, String strUserName,
119             String strPassword )
120     {
121         Git git = null;
122         Repository repository = null;
123         try
124         {
125             FileRepositoryBuilder builder = new FileRepositoryBuilder( );
126             File fGitDir = new File( sClonePath );
127 
128             CloneCommand clone = Git.cloneRepository( ).setCredentialsProvider( new UsernamePasswordCredentialsProvider( strUserName, strPassword ) )
129                     .setBare( false ).setCloneAllBranches( true ).setDirectory( fGitDir ).setURI( getRepoUrl( sRepoURL ) );
130 
131             git = clone.call( );
132 
133             repository = builder.setGitDir( fGitDir ).readEnvironment( ).findGitDir( ).build( );
134             repository.getConfig( ).setString( "user", null, "name", strGitHubUserLogin );
135             repository.getConfig( ).setString( "user", null, "email", strGitHubUserLogin + "@users.noreply.github.com" );
136             repository.getConfig( ).save( );
137 
138         }
139         catch( InvalidRemoteException e )
140         {
141 
142             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
143 
144         }
145         catch( TransportException e )
146         {
147             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
148 
149         }
150         catch( IOException e )
151         {
152             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
153         }
154         catch( GitAPIException e )
155         {
156 
157             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
158         }
159         finally
160         {
161             if ( repository != null )
162             {
163                 repository.close( );
164             }
165         }
166         return git;
167 
168     }
169 
170     /**
171      * Checkout repo branch.
172      *
173      * @param git
174      *            the git
175      * @param sBranchName
176      *            the s branch name
177      * @param commandResult
178      *            the command result
179      */
180     public static void checkoutRepoBranch( Git git, String sBranchName, CommandResult commandResult )
181     {
182         try
183         {
184             git.checkout( ).setName( sBranchName ).call( );
185 
186         }
187         catch( InvalidRemoteException e )
188         {
189 
190             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
191 
192         }
193         catch( TransportException e )
194         {
195             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
196 
197         }
198 
199         catch( GitAPIException e )
200         {
201             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
202         }
203 
204     }
205 
206     /**
207      * Creates the local branch.
208      *
209      * @param git
210      *            the git
211      * @param sBranchName
212      *            the s branch name
213      * @param commandResult
214      *            the command result
215      */
216     public static void createLocalBranch( Git git, String sBranchName, CommandResult commandResult )
217     {
218         try
219         {
220             git.branchCreate( ).setName( sBranchName ).setUpstreamMode( SetupUpstreamMode.SET_UPSTREAM ).setStartPoint( "origin/" + sBranchName )
221                     .setForce( true ).call( );
222         }
223         catch( InvalidRemoteException e )
224         {
225 
226             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
227 
228         }
229         catch( TransportException e )
230         {
231             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
232 
233         }
234 
235         catch( GitAPIException e )
236         {
237             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
238         }
239 
240     }
241 
242     /**
243      * Gets the ref branch.
244      *
245      * @param git
246      *            the git
247      * @param sBranchName
248      *            the s branch name
249      * @param commandResult
250      *            the command result
251      * @return the ref branch
252      */
253     public static String getRefBranch( Git git, String sBranchName, CommandResult commandResult )
254     {
255 
256         String refLastCommit = null;
257         try
258         {
259             git.checkout( ).setName( sBranchName ).call( );
260             refLastCommit = getLastCommitId( git );
261         }
262 
263         catch( RefAlreadyExistsException e )
264         {
265             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
266         }
267         catch( RefNotFoundException e )
268         {
269             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
270         }
271         catch( InvalidRefNameException e )
272         {
273             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
274         }
275         catch( CheckoutConflictException e )
276         {
277             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
278         }
279         catch( GitAPIException e )
280         {
281             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
282         }
283         return refLastCommit;
284     }
285 
286     /**
287      * Push force.
288      *
289      * @param git
290      *            the git
291      * @param strRefSpec
292      *            the str ref spec
293      * @param strUserName
294      *            the str user name
295      * @param strPassword
296      *            the str password
297      * @throws InvalidRemoteException
298      *             the invalid remote exception
299      * @throws TransportException
300      *             the transport exception
301      * @throws GitAPIException
302      *             the git API exception
303      */
304     public static void pushForce( Git git, String strRefSpec, String strUserName, String strPassword )
305             throws InvalidRemoteException, TransportException, GitAPIException
306     {
307 
308         git.push( ).setRemote( "origin" ).setRefSpecs( new RefSpec( strRefSpec ) ).setForce( true )
309                 .setCredentialsProvider( new UsernamePasswordCredentialsProvider( strUserName, strPassword ) ).call( );
310 
311     }
312 
313     /**
314      * Pull repo branch.
315      *
316      * @param git
317      *            the git
318      * @param sBranchName
319      *            the s branch name
320      * @param strUserName
321      *            the str user name
322      * @param strPassword
323      *            the str password
324      * @return the pull result
325      * @throws IOException
326      *             Signals that an I/O exception has occurred.
327      * @throws WrongRepositoryStateException
328      *             the wrong repository state exception
329      * @throws InvalidConfigurationException
330      *             the invalid configuration exception
331      * @throws DetachedHeadException
332      *             the detached head exception
333      * @throws InvalidRemoteException
334      *             the invalid remote exception
335      * @throws CanceledException
336      *             the canceled exception
337      * @throws RefNotFoundException
338      *             the ref not found exception
339      * @throws NoHeadException
340      *             the no head exception
341      * @throws TransportException
342      *             the transport exception
343      * @throws GitAPIException
344      *             the git API exception
345      */
346     public static PullResult pullRepoBranch( Git git, String sBranchName, String strUserName, String strPassword )
347             throws IOException, WrongRepositoryStateException, InvalidConfigurationException, DetachedHeadException, InvalidRemoteException, CanceledException,
348             RefNotFoundException, NoHeadException, TransportException, GitAPIException
349     {
350         PullResult pPullResult = git.pull( ).setCredentialsProvider( new UsernamePasswordCredentialsProvider( strUserName, strPassword ) ).setRemote( "origin" )
351                 .setRemoteBranchName( sBranchName ).call( );
352 
353         return pPullResult;
354     }
355 
356     /**
357      * Merge repo branch.
358      *
359      * @param git
360      *            the git
361      * @param strBranchToMerge
362      *            the str branch to merge
363      * @return the merge result
364      * @throws IOException
365      *             Signals that an I/O exception has occurred.
366      * @throws WrongRepositoryStateException
367      *             the wrong repository state exception
368      * @throws InvalidConfigurationException
369      *             the invalid configuration exception
370      * @throws DetachedHeadException
371      *             the detached head exception
372      * @throws InvalidRemoteException
373      *             the invalid remote exception
374      * @throws CanceledException
375      *             the canceled exception
376      * @throws RefNotFoundException
377      *             the ref not found exception
378      * @throws NoHeadException
379      *             the no head exception
380      * @throws TransportException
381      *             the transport exception
382      * @throws GitAPIException
383      *             the git API exception
384      */
385     public static MergeResult mergeRepoBranch( Git git, String strBranchToMerge )
386             throws IOException, WrongRepositoryStateException, InvalidConfigurationException, DetachedHeadException, InvalidRemoteException, CanceledException,
387             RefNotFoundException, NoHeadException, TransportException, GitAPIException
388     {
389         List<Ref> call = git.branchList( ).call( );
390         Ref mergedBranchRef = null;
391         for ( Ref ref : call )
392         {
393             if ( ref.getName( ).equals( "refs/heads/" + strBranchToMerge ) )
394             {
395                 mergedBranchRef = ref;
396                 break;
397             }
398         }
399         MergeResult mergeResult = git.merge( ).include( mergedBranchRef ).call( );
400         return mergeResult;
401     }
402 
403     /**
404      * Gets the last log.
405      *
406      * @param git
407      *            the git
408      * @param nMaxCommit
409      *            the n max commit
410      * @return the last log
411      * @throws NoHeadException
412      *             the no head exception
413      * @throws GitAPIException
414      *             the git API exception
415      */
416     public static String getLastLog( Git git, int nMaxCommit ) throws NoHeadException, GitAPIException
417     {
418         Iterable<RevCommit> logList = git.log( ).setMaxCount( 1 ).call( );
419         Iterator i = logList.iterator( );
420         String sCommitMessages = "";
421         while ( i.hasNext( ) )
422         {
423             RevCommit revCommit = (RevCommit) i.next( );
424             sCommitMessages += revCommit.getFullMessage( );
425             sCommitMessages += "\n";
426             sCommitMessages += revCommit.getCommitterIdent( );
427         }
428         return sCommitMessages;
429     }
430 
431     /**
432      * Gets the last commit id.
433      *
434      * @param git
435      *            the git
436      * @return the last commit id
437      * @throws NoHeadException
438      *             the no head exception
439      * @throws GitAPIException
440      *             the git API exception
441      */
442     public static String getLastCommitId( Git git ) throws NoHeadException, GitAPIException
443     {
444         Iterable<RevCommit> logList = git.log( ).setMaxCount( 1 ).call( );
445         Iterator i = logList.iterator( );
446         String strCommitId = null;
447         while ( i.hasNext( ) )
448         {
449             RevCommit revCommit = (RevCommit) i.next( );
450             strCommitId = revCommit.getName( );
451 
452         }
453         return strCommitId;
454     }
455 
456     /**
457      * Merge back.
458      *
459      * @param git
460      *            the git
461      * @param strUserName
462      *            the str user name
463      * @param strPassword
464      *            the str password
465      * @param commandResult
466      *            the command result
467      * @return the merge result
468      * @throws IOException
469      *             Signals that an I/O exception has occurred.
470      * @throws GitAPIException
471      *             the git API exception
472      */
473     public static MergeResult mergeBack( Git git, String strUserName, String strPassword, CommandResult commandResult ) throws IOException, GitAPIException
474     {
475 
476         Ref tag = getTagLinkedToLastRelease( git );
477 
478         git.checkout( ).setName( MASTER_BRANCH ).call( );
479         List<Ref> call = git.branchList( ).call( );
480 
481         Ref mergedBranchRef = null;
482         for ( Ref ref : call )
483         {
484             if ( ref.getName( ).equals( "refs/heads/" + DEFAULT_RELEASE_BRANCH ) )
485             {
486                 mergedBranchRef = ref;
487                 break;
488             }
489         }
490 
491         if ( tag != null )
492         {
493             mergedBranchRef = tag;
494         }
495         MergeResult mergeResult = git.merge( ).include( mergedBranchRef ).call( );
496         if ( mergeResult.getMergeStatus( ).equals( MergeResult.MergeStatus.CHECKOUT_CONFLICT )
497                 || mergeResult.getMergeStatus( ).equals( MergeResult.MergeStatus.CONFLICTING )
498                 || mergeResult.getMergeStatus( ).equals( MergeResult.MergeStatus.FAILED )
499                 || mergeResult.getMergeStatus( ).equals( MergeResult.MergeStatus.NOT_SUPPORTED ) )
500         {
501 
502             ReleaserUtils.addTechnicalError( commandResult,
503                     mergeResult.getMergeStatus( ).toString( ) + "\nPlease merge manually master into" + DEFAULT_RELEASE_BRANCH + "branch." );
504         }
505         else
506         {
507             git.push( ).setCredentialsProvider( new UsernamePasswordCredentialsProvider( strUserName, strPassword ) ).call( );
508             commandResult.getLog( ).append( mergeResult.getMergeStatus( ) );
509         }
510         return mergeResult;
511 
512     }
513 
514     /**
515      * Search repo.
516      *
517      * @param strSearch
518      *            the str search
519      * @param strOrganization
520      *            the str organization
521      * @param strUserName
522      *            the str user name
523      * @param strPassword
524      *            the str password
525      * @return the github search result
526      */
527     public static GithubSearchResult searchRepo( String strSearch, String strOrganization, String strUserName, String strPassword )
528     {
529         HttpAccess httpAccess = new HttpAccess( );
530 
531         GithubSearchResult searchResult = null;
532 
533         String strUrl = null;
534         try
535         {
536             strUrl = MessageFormat.format( AppPropertiesService.getProperty( ConstanteUtils.PROPERTY_GITHUB_SEARCH_REPO_API ),
537                     URLEncoder.encode( strSearch, "UTF-8" ), strOrganization );
538         }
539         catch( UnsupportedEncodingException e1 )
540         {
541             AppLogService.error( e1 );
542         }
543 
544         String strResponse = "";
545 
546         try
547         {
548 
549             String strApiToken = AppPropertiesService.getProperty( ConstanteUtils.PROPERTY_GITHUB_SEARCH_REPO_API_TOKEN );
550             Map<String, String> mapHeaderToken = new HashMap<String, String>( );
551             mapHeaderToken.put( "Authorization", "token " + strApiToken );
552             strResponse = httpAccess.doGet( strUrl, null, null, mapHeaderToken );
553 
554             if ( !StringUtils.isEmpty( strResponse ) )
555             {
556                 searchResult = MapperJsonUtil.parse( strResponse, GithubSearchResult.class );
557 
558             }
559 
560         }
561         catch( HttpAccessException ex )
562         {
563             AppLogService.error( ex );
564         }
565         catch( IOException e )
566         {
567             AppLogService.error( e );
568         }
569 
570         return searchResult;
571     }
572 
573     /**
574      * Gets the file content.
575      *
576      * @param strFullName
577      *            the str full name
578      * @param strPathFile
579      *            the str path file
580      * @param strBranch
581      *            the str branch
582      * @param strUserName
583      *            the str user name
584      * @param strPassword
585      *            the str password
586      * @return the file content
587      */
588     public static String getFileContent( String strFullName, String strPathFile, String strBranch, String strUserName, String strPassword )
589     {
590         HttpAccess httpAccess = new HttpAccess( );
591         String strUrl = "https://raw.githubusercontent.com/" + strFullName + "/" + strBranch + "/" + strPathFile;
592         // Map<String,String> hashHeader=new HashMap<>( );
593         // hashHeader.put( "accept", "application/vnd.github.VERSION.raw" );
594         String strResponse = "";
595 
596         try
597         {
598 
599             strResponse = httpAccess.doGet( strUrl, new BasicAuthorizationAuthenticator( strUserName, strPassword ), null );
600 
601         }
602         catch( HttpAccessException ex )
603         {
604             AppLogService.error( ex );
605         }
606 
607         return strResponse;
608     }
609 
610     /**
611      * Gets the tag linked to last release.
612      *
613      * @param git
614      *            the git
615      * @return the tag linked to last release
616      * @throws GitAPIException
617      *             the git API exception
618      */
619     private static Ref getTagLinkedToLastRelease( Git git ) throws GitAPIException
620     {
621         final String TOKEN = "[maven-release-plugin] prepare release ";
622         Ref res = null;
623         String sTagName = null;
624 
625         Iterable<RevCommit> logList = git.log( ).setMaxCount( 10 ).call( );
626         Iterator i = logList.iterator( );
627         String sCommitMessages = "";
628         while ( i.hasNext( ) )
629         {
630             RevCommit revCommit = (RevCommit) i.next( );
631 
632             sCommitMessages = revCommit.getFullMessage( );
633             int index = sCommitMessages.indexOf( TOKEN );
634             if ( index >= 0 )
635             {
636                 sTagName = sCommitMessages.replace( TOKEN, "" );
637                 break;
638             }
639         }
640 
641         if ( ( sTagName != null ) && ( !( sTagName.trim( ).equals( "" ) ) ) )
642         {
643             List<Ref> tags = git.tagList( ).call( );
644             for ( int j = 0; j < tags.size( ); j++ )
645             {
646                 Ref tag = tags.get( tags.size( ) - 1 - j );
647                 String tagName = tag.getName( );
648                 if ( ( "refs/tags/" + sTagName ).startsWith( tag.getName( ) ) )
649                 {
650                     res = tag;
651                     break;
652                 }
653             }
654         }
655 
656         return res;
657     }
658 
659     /**
660      * Gets the tag name list.
661      *
662      * @param git
663      *            the git
664      * @return the tag name list
665      */
666     public static List<String> getTagNameList( Git git )
667     {
668         List<String> listTagName = null;
669         if ( git != null )
670         {
671             listTagName = new ArrayList<>( );
672             Collection<Ref> colTags = git.getRepository( ).getTags( ).values( );
673             for ( Ref ref : colTags )
674             {
675                 listTagName.add( ref.getName( ).replace( CONSTANTE_REF_TAG, "" ) );
676             }
677         }
678 
679         return listTagName;
680     }
681 
682     /**
683      * Gets the repo url.
684      *
685      * @param strRepoUrl
686      *            the str repo url
687      * @return the repo url
688      */
689     public static String getRepoUrl( String strRepoUrl )
690     {
691 
692         if ( strRepoUrl != null && strRepoUrl.startsWith( "scm:git:" ) )
693         {
694             strRepoUrl = strRepoUrl.substring( 8 );
695 
696         }
697 
698         return strRepoUrl;
699 
700     }
701 
702     /**
703      * Gets the git.
704      *
705      * @param strClonePath
706      *            the str clone path
707      * @return the git
708      */
709     public static Git getGit( String strClonePath )
710     {
711         Git git = null;
712         Repository repository = null;
713 
714         File fGitDir = new File( strClonePath + "/.git" );
715 
716         if ( !fGitDir.exists( ) )
717         {
718             return null;
719         }
720 
721         try
722         {
723             FileRepositoryBuilder builder = new FileRepositoryBuilder( );
724             repository = builder.setGitDir( fGitDir ).readEnvironment( ).findGitDir( ).build( );
725 
726             git = new Git( repository );
727         }
728         catch( IOException e )
729         {
730             AppLogService.error( e.getMessage( ), e );
731         }
732 
733         return git;
734     }
735 
736     public static List<String> getBranchList( String repoUrl, File localRepo, CommandResult commandResult, String login, String pwd )
737     {
738         Git git = null;
739         List<String> branchNameList = null;
740 
741         try
742         {
743             CredentialsProvider credential = new UsernamePasswordCredentialsProvider( login, pwd );
744 
745             git = Git.cloneRepository( ).setCredentialsProvider( credential ).setURI( repoUrl ).setDirectory( localRepo ).setCloneAllBranches( true ).call( );
746 
747             branchNameList = new ArrayList<String>( );
748 
749             List<Ref> branchList = git.branchList( ).setListMode( ListMode.ALL ).call( );
750             if ( !branchList.isEmpty( ) )
751             {
752                 for ( Ref ref : branchList )
753                 {
754                     String [ ] refSplit = ref.getName( ).split( "/" );
755 
756                     if ( refSplit [1].equals( "remotes" ) && refSplit [2].equals( "origin" ) )
757                     {
758                         branchNameList.add( refSplit [3] );
759                     }
760                 }
761             }
762         }
763         catch( InvalidRemoteException e )
764         {
765             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
766             branchNameList.add( "InvalidRemoteException" );
767         }
768         catch( TransportException e )
769         {
770             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
771             branchNameList.add( "TransportException" );
772         }
773         catch( GitAPIException e )
774         {
775             ReleaserUtils.addTechnicalError( commandResult, e.getMessage( ), e );
776             branchNameList.add( "GitAPIException)" );
777         }
778         finally
779         {
780             if ( git != null )
781             {
782                 git.close( );
783             }
784         }
785 
786         return branchNameList;
787     }
788 }