1 package org.apache.maven.scm.provider.git.jgit.command.checkout;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.scm.ScmException;
23 import org.apache.maven.scm.ScmFile;
24 import org.apache.maven.scm.ScmFileSet;
25 import org.apache.maven.scm.ScmFileStatus;
26 import org.apache.maven.scm.ScmTag;
27 import org.apache.maven.scm.ScmVersion;
28 import org.apache.maven.scm.command.checkout.AbstractCheckOutCommand;
29 import org.apache.maven.scm.command.checkout.CheckOutScmResult;
30 import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
31 import org.apache.maven.scm.provider.ScmProviderRepository;
32 import org.apache.maven.scm.provider.git.command.GitCommand;
33 import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
34 import org.apache.maven.scm.provider.git.jgit.command.branch.JGitBranchCommand;
35 import org.apache.maven.scm.provider.git.jgit.command.remoteinfo.JGitRemoteInfoCommand;
36 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
37 import org.codehaus.plexus.util.StringUtils;
38 import org.eclipse.jgit.api.Git;
39 import org.eclipse.jgit.lib.Constants;
40 import org.eclipse.jgit.lib.ProgressMonitor;
41 import org.eclipse.jgit.revwalk.RevCommit;
42 import org.eclipse.jgit.revwalk.RevWalk;
43 import org.eclipse.jgit.storage.file.WindowCacheConfig;
44 import org.eclipse.jgit.transport.CredentialsProvider;
45 import org.eclipse.jgit.treewalk.TreeWalk;
46
47 import java.io.File;
48 import java.util.ArrayList;
49 import java.util.List;
50 import java.util.Set;
51
52
53
54
55
56
57 public class JGitCheckOutCommand
58 extends AbstractCheckOutCommand
59 implements GitCommand
60 {
61
62
63
64
65
66
67 protected CheckOutScmResult executeCheckOutCommand( ScmProviderRepository repo, ScmFileSet fileSet,
68 ScmVersion version, boolean recursive )
69 throws ScmException
70 {
71 GitScmProviderRepository repository = (GitScmProviderRepository) repo;
72
73 if ( GitScmProviderRepository.PROTOCOL_FILE.equals( repository.getFetchInfo().getProtocol() )
74 && repository.getFetchInfo().getPath().indexOf( fileSet.getBasedir().getPath() ) >= 0 )
75 {
76 throw new ScmException( "remote repository must not be the working directory" );
77 }
78
79 Git git = null;
80 try
81 {
82
83 ProgressMonitor monitor = JGitUtils.getMonitor( getLogger() );
84
85 String branch = version != null ? version.getName() : null;
86
87 if ( StringUtils.isBlank( branch ) )
88 {
89 branch = Constants.MASTER;
90 }
91
92 getLogger().debug( "try checkout of branch: " + branch );
93
94 if ( !fileSet.getBasedir().exists() || !( new File( fileSet.getBasedir(), ".git" ).exists() ) )
95 {
96 if ( fileSet.getBasedir().exists() )
97 {
98
99 fileSet.getBasedir().delete();
100 }
101
102
103 WindowCacheConfig cfg = new WindowCacheConfig();
104 cfg.setPackedGitMMAP( false );
105 cfg.install();
106
107
108 CredentialsProvider credentials = JGitUtils.getCredentials( (GitScmProviderRepository) repo );
109 getLogger().info( "cloning [" + branch + "] to " + fileSet.getBasedir() );
110 git = Git.cloneRepository().setURI( repository.getFetchUrl() ).setCredentialsProvider( credentials ).setBranch( branch ).setDirectory( fileSet.getBasedir() ).setProgressMonitor( monitor ).call();
111 }
112
113 JGitRemoteInfoCommand remoteInfoCommand = new JGitRemoteInfoCommand();
114 remoteInfoCommand.setLogger( getLogger() );
115 RemoteInfoScmResult result = remoteInfoCommand.executeRemoteInfoCommand( repository, fileSet, null );
116
117 if(git == null) {
118 git = Git.open( fileSet.getBasedir() );
119 }
120
121 if ( fileSet.getBasedir().exists() && new File( fileSet.getBasedir(), ".git" ).exists()
122 && result.getBranches().size() > 0 )
123 {
124
125 CredentialsProvider credentials = JGitUtils.prepareSession( getLogger(), git, repository );
126
127 if ( version != null && StringUtils.isNotEmpty( version.getName() ) && ( version instanceof ScmTag ) )
128 {
129
130
131
132
133
134 getLogger().debug( "fetch..." );
135 git.fetch().setCredentialsProvider( credentials ).setProgressMonitor( monitor ).call();
136 }
137 else
138 {
139 getLogger().debug( "pull..." );
140 git.pull().setCredentialsProvider( credentials ).setProgressMonitor( monitor ).call();
141
142 }
143 }
144
145 Set<String> localBranchNames = JGitBranchCommand.getShortLocalBranchNames( git );
146 if ( version instanceof ScmTag )
147 {
148 getLogger().info( "checkout tag [" + branch + "] at " + fileSet.getBasedir() );
149 git.checkout().setName( branch ).call();
150 }
151 else if ( localBranchNames.contains( branch ) )
152 {
153 getLogger().info( "checkout [" + branch + "] at " + fileSet.getBasedir() );
154 git.checkout().setName( branch ).call();
155 }
156 else
157 {
158 getLogger().info( "checkout remote branch [" + branch + "] at " + fileSet.getBasedir() );
159 git.checkout().setName( branch ).setCreateBranch( true ).setStartPoint( Constants.DEFAULT_REMOTE_NAME
160 + "/" + branch ).call();
161 }
162
163 RevWalk revWalk = new RevWalk( git.getRepository() );
164 RevCommit commit = revWalk.parseCommit( git.getRepository().resolve( Constants.HEAD ) );
165 revWalk.release();
166
167 final TreeWalk walk = new TreeWalk( git.getRepository() );
168 walk.reset();
169 walk.setRecursive( true );
170 walk.addTree( commit.getTree() );
171
172 List<ScmFile> listedFiles = new ArrayList<ScmFile>();
173 while ( walk.next() )
174 {
175 listedFiles.add( new ScmFile( walk.getPathString(), ScmFileStatus.CHECKED_OUT ) );
176 }
177 walk.release();
178
179 getLogger().debug( "current branch: " + git.getRepository().getBranch() );
180
181 return new CheckOutScmResult( "checkout via JGit", listedFiles );
182 }
183 catch ( Exception e )
184 {
185 throw new ScmException( "JGit checkout failure!", e );
186 }
187 finally
188 {
189 JGitUtils.closeRepo( git );
190 }
191 }
192
193 }