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.checkin;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.net.URI;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.apache.commons.io.FilenameUtils;
30 import org.apache.maven.scm.ScmException;
31 import org.apache.maven.scm.ScmFile;
32 import org.apache.maven.scm.ScmFileSet;
33 import org.apache.maven.scm.ScmFileStatus;
34 import org.apache.maven.scm.ScmVersion;
35 import org.apache.maven.scm.command.checkin.AbstractCheckInCommand;
36 import org.apache.maven.scm.command.checkin.CheckInScmResult;
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.add.GitAddCommand;
41 import org.apache.maven.scm.provider.git.gitexe.command.branch.GitBranchCommand;
42 import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand;
43 import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusConsumer;
44 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
45 import org.apache.maven.scm.provider.git.util.GitUtil;
46 import org.codehaus.plexus.util.FileUtils;
47 import org.codehaus.plexus.util.Os;
48 import org.codehaus.plexus.util.cli.CommandLineUtils;
49 import org.codehaus.plexus.util.cli.Commandline;
50
51
52
53
54
55
56 public class GitCheckInCommand extends AbstractCheckInCommand implements GitCommand {
57 private final Map<String, String> environmentVariables;
58
59 public GitCheckInCommand(Map<String, String> environmentVariables) {
60 super();
61 this.environmentVariables = environmentVariables;
62 }
63
64
65 protected CheckInScmResult executeCheckInCommand(
66 ScmProviderRepository repo, ScmFileSet fileSet, String message, ScmVersion version) throws ScmException {
67 GitScmProviderRepository repository = (GitScmProviderRepository) repo;
68
69 CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
70 CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
71
72 int exitCode = -1;
73
74 File messageFile = FileUtils.createTempFile("maven-scm-", ".commit", null);
75 try {
76 FileUtils.fileWrite(messageFile.getAbsolutePath(), "UTF-8", message);
77 } catch (IOException ex) {
78 return new CheckInScmResult(
79 null,
80 "Error while making a temporary file for the commit message: " + ex.getMessage(),
81 null,
82 false);
83 }
84
85 try {
86 if (!fileSet.getFileList().isEmpty()) {
87
88
89
90 Commandline clAdd = null;
91
92
93 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
94 for (File file : fileSet.getFileList()) {
95 clAdd = GitAddCommand.createCommandLine(fileSet.getBasedir(), Collections.singletonList(file));
96 exitCode = GitCommandLineUtils.execute(clAdd, stdout, stderr);
97
98 if (exitCode != 0) {
99 break;
100 }
101 }
102 } else {
103 clAdd = GitAddCommand.createCommandLine(fileSet.getBasedir(), fileSet.getFileList());
104 exitCode = GitCommandLineUtils.execute(clAdd, stdout, stderr);
105 }
106
107 if (exitCode != 0) {
108 return new CheckInScmResult(
109 clAdd.toString(), "The git-add command failed.", stderr.getOutput(), false);
110 }
111 }
112
113
114
115 URI relativeRepositoryPath = GitStatusCommand.getRelativeCWD(logger, fileSet);
116
117
118
119
120 Commandline clStatus = GitStatusCommand.createCommandLine(repository, fileSet);
121
122 GitStatusConsumer statusConsumer =
123 new GitStatusConsumer(fileSet.getBasedir(), relativeRepositoryPath, fileSet);
124 exitCode = GitCommandLineUtils.execute(clStatus, statusConsumer, stderr);
125 if (exitCode != 0) {
126
127 if (logger.isInfoEnabled()) {
128 logger.info("nothing added to commit but untracked files present (use \"git add\" to " + "track)");
129 }
130 }
131
132 if (statusConsumer.getChangedFiles().isEmpty()) {
133 return new CheckInScmResult(null, statusConsumer.getChangedFiles());
134 }
135
136 Commandline clCommit = createCommitCommandLine(repository, fileSet, messageFile, environmentVariables);
137
138 exitCode = GitCommandLineUtils.execute(clCommit, stdout, stderr);
139 if (exitCode != 0) {
140 return new CheckInScmResult(
141 clCommit.toString(), "The git-commit command failed.", stderr.getOutput(), false);
142 }
143
144 if (repo.isPushChanges()) {
145 Commandline cl = createPushCommandLine(repository, fileSet, version);
146
147 exitCode = GitCommandLineUtils.execute(cl, stdout, stderr);
148 if (exitCode != 0) {
149 return new CheckInScmResult(
150 cl.toString(), "The git-push command failed.", stderr.getOutput(), false);
151 }
152 }
153
154 List<ScmFile> checkedInFiles =
155 new ArrayList<>(statusConsumer.getChangedFiles().size());
156
157
158 for (ScmFile changedFile : statusConsumer.getChangedFiles()) {
159 ScmFile scmfile = new ScmFile(changedFile.getPath(), ScmFileStatus.CHECKED_IN);
160
161 if (fileSet.getFileList().isEmpty()) {
162 checkedInFiles.add(scmfile);
163 } else {
164
165 for (File f : fileSet.getFileList()) {
166 if (FilenameUtils.separatorsToUnix(f.getPath()).equals(scmfile.getPath())) {
167 checkedInFiles.add(scmfile);
168 }
169 }
170 }
171 }
172
173 return new CheckInScmResult(clCommit.toString(), checkedInFiles);
174 } finally {
175 try {
176 FileUtils.forceDelete(messageFile);
177 } catch (IOException ex) {
178
179 }
180 }
181 }
182
183
184
185
186
187 public Commandline createPushCommandLine(
188 GitScmProviderRepository repository, ScmFileSet fileSet, ScmVersion version) throws ScmException {
189 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine(
190 fileSet.getBasedir(), "push", repository, environmentVariables);
191
192 String branch = GitBranchCommand.getCurrentBranch(repository, fileSet);
193
194 if (branch == null || branch.length() == 0) {
195 throw new ScmException("Could not detect the current branch. Don't know where I should push to!");
196 }
197
198 cl.createArg().setValue(repository.getPushUrl());
199
200 cl.createArg().setValue("refs/heads/" + branch + ":" + "refs/heads/" + branch);
201
202 return cl;
203 }
204
205 public static Commandline createCommitCommandLine(
206 GitScmProviderRepository repository, ScmFileSet fileSet, File messageFile) throws ScmException {
207 return createCommitCommandLine(repository, fileSet, messageFile, Collections.emptyMap());
208 }
209
210 public static Commandline createCommitCommandLine(
211 GitScmProviderRepository repository,
212 ScmFileSet fileSet,
213 File messageFile,
214 Map<String, String> environmentVariables)
215 throws ScmException {
216 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine(fileSet.getBasedir(), "commit");
217
218 cl.createArg().setValue("--verbose");
219
220 cl.createArg().setValue("-F");
221
222 cl.createArg().setValue(messageFile.getAbsolutePath());
223
224 if (fileSet.getFileList().isEmpty()) {
225
226 cl.createArg().setValue("-a");
227 }
228
229 if (GitUtil.getSettings().isCommitNoVerify()) {
230 cl.createArg().setValue("--no-verify");
231 }
232
233 return cl;
234 }
235 }