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