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