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