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