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