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