1 package org.apache.maven.scm.provider.git.gitexe.command.checkout;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23
24 import org.apache.maven.scm.CommandParameter;
25 import org.apache.maven.scm.CommandParameters;
26 import org.apache.maven.scm.ScmBranch;
27 import org.apache.maven.scm.ScmException;
28 import org.apache.maven.scm.ScmFileSet;
29 import org.apache.maven.scm.ScmFileStatus;
30 import org.apache.maven.scm.ScmResult;
31 import org.apache.maven.scm.ScmTag;
32 import org.apache.maven.scm.ScmVersion;
33 import org.apache.maven.scm.command.checkout.AbstractCheckOutCommand;
34 import org.apache.maven.scm.command.checkout.CheckOutScmResult;
35 import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
36 import org.apache.maven.scm.provider.ScmProviderRepository;
37 import org.apache.maven.scm.provider.git.command.GitCommand;
38 import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils;
39 import org.apache.maven.scm.provider.git.gitexe.command.list.GitListCommand;
40 import org.apache.maven.scm.provider.git.gitexe.command.list.GitListConsumer;
41 import org.apache.maven.scm.provider.git.gitexe.command.remoteinfo.GitRemoteInfoCommand;
42 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
43 import org.codehaus.plexus.util.StringUtils;
44 import org.codehaus.plexus.util.cli.CommandLineUtils;
45 import org.codehaus.plexus.util.cli.Commandline;
46
47
48
49
50
51 public class GitCheckOutCommand
52 extends AbstractCheckOutCommand
53 implements GitCommand
54 {
55
56
57
58
59
60
61
62
63 @Override
64 public ScmResult executeCommand( ScmProviderRepository repo, ScmFileSet fileSet,
65 CommandParameters parameters )
66 throws ScmException
67 {
68 ScmVersion version = parameters.getScmVersion( CommandParameter.SCM_VERSION, null );
69 boolean binary = parameters.getBoolean( CommandParameter.BINARY, false );
70 boolean shallow = parameters.getBoolean( CommandParameter.SHALLOW, false );
71
72 GitScmProviderRepository repository = (GitScmProviderRepository) repo;
73
74 if ( GitScmProviderRepository.PROTOCOL_FILE.equals( repository.getFetchInfo().getProtocol() )
75 && repository.getFetchInfo().getPath().indexOf( fileSet.getBasedir().getPath() ) >= 0 )
76 {
77 throw new ScmException( "remote repository must not be the working directory" );
78 }
79
80 int exitCode;
81
82 CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
83 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
84
85 String lastCommandLine = "git-nothing-to-do";
86
87 if ( !fileSet.getBasedir().exists() || !( new File( fileSet.getBasedir(), ".git" ).exists() ) )
88 {
89 if ( fileSet.getBasedir().exists() )
90 {
91
92 fileSet.getBasedir().delete();
93 }
94
95
96 Commandline clClone = createCloneCommand( repository, fileSet.getBasedir(), version, binary, shallow );
97
98 exitCode = GitCommandLineUtils.execute( clClone, stdout, stderr, getLogger() );
99 if ( exitCode != 0 )
100 {
101 return new CheckOutScmResult( clClone.toString(), "The git-clone command failed.", stderr.getOutput(),
102 false );
103 }
104 lastCommandLine = clClone.toString();
105 }
106
107 GitRemoteInfoCommand gitRemoteInfoCommand = new GitRemoteInfoCommand();
108 gitRemoteInfoCommand.setLogger( getLogger() );
109 RemoteInfoScmResult result = gitRemoteInfoCommand.executeRemoteInfoCommand( repository, null, null );
110
111 if ( fileSet.getBasedir().exists() && new File( fileSet.getBasedir(), ".git" ).exists()
112 && result.getBranches().size() > 0 )
113 {
114
115 Commandline clPull = createPullCommand( repository, fileSet.getBasedir(), version );
116
117 exitCode = GitCommandLineUtils.execute( clPull, stdout, stderr, getLogger() );
118 if ( exitCode != 0 )
119 {
120 return new CheckOutScmResult( clPull.toString(), "The git-pull command failed.", stderr.getOutput(),
121 false );
122 }
123 lastCommandLine = clPull.toString();
124
125
126 Commandline clCheckout = createCommandLine( repository, fileSet.getBasedir(), version );
127
128 exitCode = GitCommandLineUtils.execute( clCheckout, stdout, stderr, getLogger() );
129 if ( exitCode != 0 )
130 {
131 return new CheckOutScmResult( clCheckout.toString(), "The git-checkout command failed.",
132 stderr.getOutput(), false );
133 }
134 lastCommandLine = clCheckout.toString();
135 }
136
137
138 GitListConsumer listConsumer =
139 new GitListConsumer( getLogger(), fileSet.getBasedir(), ScmFileStatus.CHECKED_IN );
140
141 Commandline clList = GitListCommand.createCommandLine( repository, fileSet.getBasedir() );
142
143 exitCode = GitCommandLineUtils.execute( clList, listConsumer, stderr, getLogger() );
144 if ( exitCode != 0 )
145 {
146 return new CheckOutScmResult( clList.toString(), "The git-ls-files command failed.", stderr.getOutput(),
147 false );
148 }
149
150 return new CheckOutScmResult( lastCommandLine, listConsumer.getListedFiles() );
151 }
152
153
154
155
156
157 public static Commandline createCommandLine( GitScmProviderRepository repository, File workingDirectory,
158 ScmVersion version )
159 {
160 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "checkout" );
161
162 if ( version != null && StringUtils.isNotEmpty( version.getName() ) )
163 {
164 cl.createArg().setValue( version.getName() );
165 }
166
167 return cl;
168 }
169
170
171
172
173 private Commandline createCloneCommand( GitScmProviderRepository repository, File workingDirectory,
174 ScmVersion version, boolean binary, boolean shallow )
175 {
176 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory.getParentFile(), "clone" );
177
178 forceBinary( cl, binary );
179
180 if ( shallow )
181 {
182 cl.createArg().setValue( "--depth" );
183
184 cl.createArg().setValue( "1" );
185 }
186
187 if ( version != null && ( version instanceof ScmBranch ) )
188 {
189
190 cl.createArg().setValue( "--branch" );
191
192 cl.createArg().setValue( version.getName() );
193 }
194
195 cl.createArg().setValue( repository.getFetchUrl() );
196
197 cl.createArg().setValue( workingDirectory.getName() );
198
199 return cl;
200 }
201
202 private void forceBinary( Commandline cl, boolean binary )
203 {
204 if ( binary )
205 {
206 cl.createArg().setValue( "-c" );
207 cl.createArg().setValue( "core.autocrlf=false" );
208 }
209 }
210
211
212
213
214 private Commandline createPullCommand( GitScmProviderRepository repository, File workingDirectory,
215 ScmVersion version )
216 {
217 Commandline cl;
218
219 if ( version != null && StringUtils.isNotEmpty( version.getName() ) )
220 {
221 if ( version instanceof ScmTag )
222 {
223
224
225
226
227
228 cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "fetch" );
229
230 cl.createArg().setValue( repository.getFetchUrl() );
231 }
232 else
233 {
234 cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull" );
235
236 cl.createArg().setValue( repository.getFetchUrl() );
237
238 cl.createArg().setValue( version.getName() + ":" + version.getName() );
239 }
240 }
241 else
242 {
243 cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "pull" );
244
245 cl.createArg().setValue( repository.getFetchUrl() );
246 cl.createArg().setValue( "master" );
247 }
248 return cl;
249 }
250
251
252
253
254
255
256
257 protected CheckOutScmResult executeCheckOutCommand( ScmProviderRepository repo, ScmFileSet fileSet,
258 ScmVersion version, boolean recursive, boolean shallow )
259 throws ScmException
260 {
261 throw new UnsupportedOperationException( "Should not get here" );
262 }
263 }