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.jgit.command.checkin;
20
21 import java.io.File;
22 import java.net.InetAddress;
23 import java.net.UnknownHostException;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Set;
27
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.maven.scm.ScmException;
30 import org.apache.maven.scm.ScmFile;
31 import org.apache.maven.scm.ScmFileSet;
32 import org.apache.maven.scm.ScmVersion;
33 import org.apache.maven.scm.command.checkin.AbstractCheckInCommand;
34 import org.apache.maven.scm.command.checkin.CheckInScmResult;
35 import org.apache.maven.scm.provider.ScmProviderRepository;
36 import org.apache.maven.scm.provider.git.command.GitCommand;
37 import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
38 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
39 import org.eclipse.jgit.api.AddCommand;
40 import org.eclipse.jgit.api.CommitCommand;
41 import org.eclipse.jgit.api.Git;
42 import org.eclipse.jgit.api.Status;
43 import org.eclipse.jgit.lib.Constants;
44 import org.eclipse.jgit.lib.UserConfig;
45 import org.eclipse.jgit.revwalk.RevCommit;
46 import org.eclipse.jgit.transport.RefSpec;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class JGitCheckInCommand extends AbstractCheckInCommand implements GitCommand {
66
67 protected static final String GIT_MAVEN_SECTION = "maven-scm";
68
69 protected static final String GIT_MAILDOMAIN = "maildomain";
70
71 protected static final String GIT_FORCE = "forceUsername";
72
73
74
75
76 protected CheckInScmResult executeCheckInCommand(
77 ScmProviderRepository repo, ScmFileSet fileSet, String message, ScmVersion version) throws ScmException {
78
79 Git git = null;
80 try {
81 File basedir = fileSet.getBasedir();
82 git = JGitUtils.openRepo(basedir);
83
84 boolean doCommit = false;
85
86 if (!fileSet.getFileList().isEmpty()) {
87
88 doCommit = JGitUtils.addAllFiles(git, fileSet).size() > 0;
89 if (!doCommit) {
90 doCommit = git.status().call().hasUncommittedChanges();
91 }
92 } else {
93
94 Status status = git.status().call();
95 Set<String> changeds = git.status().call().getModified();
96 if (changeds.isEmpty()) {
97 if (!status.hasUncommittedChanges()) {
98
99 logger.warn("There are neither files to be added nor any uncommitted changes");
100 doCommit = false;
101 } else {
102 logger.debug("There are uncommitted changes in the git index");
103 doCommit = true;
104 }
105 } else {
106
107 AddCommand add = git.add();
108 for (String changed : changeds) {
109 logger.debug("Add manually: {}", changed);
110 add.addFilepattern(changed);
111 doCommit = true;
112 }
113 add.call();
114 }
115 }
116
117 List<ScmFile> checkedInFiles = Collections.emptyList();
118 if (doCommit) {
119 UserInfo author = getAuthor(repo, git);
120 UserInfo committer = getCommitter(repo, git);
121
122 CommitCommand command = git.commit().setMessage(message).setAuthor(author.name, author.email);
123 command.setCommitter(committer.name, committer.email);
124 RevCommit commitRev = command.call();
125
126 logger.info("commit done: " + commitRev.getShortMessage());
127 checkedInFiles = JGitUtils.getFilesInCommit(git.getRepository(), commitRev, fileSet.getBasedir());
128 if (logger.isDebugEnabled()) {
129 for (ScmFile scmFile : checkedInFiles) {
130 logger.debug("in commit: " + scmFile);
131 }
132 }
133 }
134
135 if (repo.isPushChanges()) {
136 String branch = version != null ? version.getName() : null;
137 if (StringUtils.isBlank(branch)) {
138 branch = git.getRepository().getBranch();
139 }
140 RefSpec refSpec = new RefSpec(Constants.R_HEADS + branch + ":" + Constants.R_HEADS + branch);
141 logger.info("push changes to remote... " + refSpec);
142 JGitUtils.push(git, (GitScmProviderRepository) repo, refSpec);
143 }
144
145 return new CheckInScmResult("JGit checkin", checkedInFiles);
146 } catch (Exception e) {
147 throw new ScmException("JGit checkin failure!", e);
148 } finally {
149 JGitUtils.closeRepo(git);
150 }
151 }
152
153 private static final class UserInfo {
154 final String name;
155
156 final String email;
157
158 UserInfo(String name, String email) {
159 this.name = name;
160 this.email = email;
161 }
162 }
163
164 private UserInfo getCommitter(ScmProviderRepository repo, Git git) {
165 boolean forceMvnUser = git.getRepository().getConfig().getBoolean(GIT_MAVEN_SECTION, GIT_FORCE, false);
166
167
168 UserConfig user = git.getRepository().getConfig().get(UserConfig.KEY);
169 String committerName = null;
170 if (!forceMvnUser && !user.isCommitterNameImplicit()) {
171 committerName = user.getCommitterName();
172 }
173
174
175 if (StringUtils.isBlank(committerName)) {
176 committerName = repo.getUser();
177 }
178
179
180 if (StringUtils.isBlank(committerName)) {
181 committerName = user.getCommitterName();
182 }
183
184
185 String committerMail = null;
186 if (!user.isCommitterEmailImplicit()) {
187 committerMail = user.getCommitterEmail();
188 }
189
190 if (StringUtils.isBlank(committerMail)) {
191 String defaultDomain = git.getRepository().getConfig().getString(GIT_MAVEN_SECTION, null, GIT_MAILDOMAIN);
192 defaultDomain = StringUtils.isNotBlank(defaultDomain) ? defaultDomain : getHostname();
193
194
195 committerMail = StringUtils.isNotBlank(repo.getUser())
196 ? repo.getUser() + "@" + defaultDomain
197 : user.getCommitterEmail();
198 }
199
200 return new UserInfo(committerName, committerMail);
201 }
202
203 private UserInfo getAuthor(ScmProviderRepository repo, Git git) {
204 boolean forceMvnUser = git.getRepository().getConfig().getBoolean(GIT_MAVEN_SECTION, GIT_FORCE, false);
205
206
207 UserConfig user = git.getRepository().getConfig().get(UserConfig.KEY);
208 String authorName = null;
209 if (!forceMvnUser && !user.isAuthorNameImplicit()) {
210 authorName = user.getAuthorName();
211 }
212
213
214 if (StringUtils.isBlank(authorName)) {
215 authorName = repo.getUser();
216 }
217
218
219 if (StringUtils.isBlank(authorName)) {
220 authorName = user.getAuthorName();
221 }
222
223
224 String authorMail = null;
225 if (!user.isAuthorEmailImplicit()) {
226 authorMail = user.getAuthorEmail();
227 }
228
229 if (StringUtils.isBlank(authorMail)) {
230 String defaultDomain = git.getRepository().getConfig().getString(GIT_MAVEN_SECTION, null, GIT_MAILDOMAIN);
231 defaultDomain = StringUtils.isNotBlank(defaultDomain) ? defaultDomain : getHostname();
232
233
234 authorMail = StringUtils.isNotBlank(repo.getUser())
235 ? repo.getUser() + "@" + defaultDomain
236 : user.getAuthorEmail();
237 }
238
239 return new UserInfo(authorName, authorMail);
240 }
241
242 private String getHostname() {
243 String hostname;
244 try {
245 InetAddress localhost = java.net.InetAddress.getLocalHost();
246 hostname = localhost.getHostName();
247 } catch (UnknownHostException e) {
248 logger.warn(
249 "failed to resolve hostname to create mail address, " + "defaulting to 'maven-scm-provider-jgit'");
250 hostname = "maven-scm-provider-jgit";
251 }
252 return hostname;
253 }
254 }