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 Commandline clRevparse = GitStatusCommand.createRevparseShowToplevelCommand( fileSet );
103
104 stdout = new CommandLineUtils.StringStreamConsumer();
105 stderr = new CommandLineUtils.StringStreamConsumer();
106
107 URI relativeRepositoryPath = null;
108
109 exitCode = GitCommandLineUtils.execute( clRevparse, stdout, stderr, getLogger() );
110 if ( exitCode != 0 )
111 {
112
113 if ( getLogger().isInfoEnabled() )
114 {
115 getLogger().info( "Could not resolve toplevel" );
116 }
117 }
118 else
119 {
120 relativeRepositoryPath = GitStatusConsumer.resolveURI( stdout.getOutput().trim(), fileSet.getBasedir().toURI() );
121 }
122
123
124
125
126 Commandline clStatus = GitStatusCommand.createCommandLine( repository, fileSet );
127
128 GitStatusConsumer statusConsumer = new GitStatusConsumer( getLogger(), fileSet.getBasedir(), relativeRepositoryPath );
129 exitCode = GitCommandLineUtils.execute( clStatus, statusConsumer, stderr, getLogger() );
130 if ( exitCode != 0 )
131 {
132
133 if ( getLogger().isInfoEnabled() )
134 {
135 getLogger().info( "nothing added to commit but untracked files present (use \"git add\" to " +
136 "track)" );
137 }
138 }
139
140 if ( statusConsumer.getChangedFiles().isEmpty() )
141 {
142 return new CheckInScmResult( null, statusConsumer.getChangedFiles() );
143 }
144
145 Commandline clCommit = createCommitCommandLine( repository, fileSet, messageFile );
146
147 exitCode = GitCommandLineUtils.execute( clCommit, stdout, stderr, getLogger() );
148 if ( exitCode != 0 )
149 {
150 return new CheckInScmResult( clCommit.toString(), "The git-commit command failed.", stderr.getOutput(),
151 false );
152 }
153
154 if( repo.isPushChanges() )
155 {
156 Commandline cl = createPushCommandLine( getLogger(), repository, fileSet, version );
157
158 exitCode = GitCommandLineUtils.execute( cl, stdout, stderr, getLogger() );
159 if ( exitCode != 0 )
160 {
161 return new CheckInScmResult( cl.toString(), "The git-push command failed.", stderr.getOutput(), false );
162 }
163 }
164
165 List<ScmFile> checkedInFiles = new ArrayList<ScmFile>( statusConsumer.getChangedFiles().size() );
166
167
168 for ( ScmFile changedFile : statusConsumer.getChangedFiles() )
169 {
170 ScmFile scmfile = new ScmFile( changedFile.getPath(), ScmFileStatus.CHECKED_IN );
171
172 if ( fileSet.getFileList().isEmpty() )
173 {
174 checkedInFiles.add( scmfile );
175 }
176 else
177 {
178
179 for ( File f : fileSet.getFileList() )
180 {
181 if ( FilenameUtils.separatorsToUnix( f.getPath() ).equals( scmfile.getPath() ) )
182 {
183 checkedInFiles.add( scmfile );
184 }
185
186 }
187 }
188 }
189
190 return new CheckInScmResult( clCommit.toString(), checkedInFiles );
191 }
192 finally
193 {
194 try
195 {
196 FileUtils.forceDelete( messageFile );
197 }
198 catch ( IOException ex )
199 {
200
201 }
202 }
203
204 }
205
206
207
208
209
210 public static Commandline createPushCommandLine( ScmLogger logger, GitScmProviderRepository repository,
211 ScmFileSet fileSet, ScmVersion version )
212 throws ScmException
213 {
214 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push" );
215
216 String branch = GitBranchCommand.getCurrentBranch( logger, repository, fileSet );
217
218 if ( branch == null || branch.length() == 0 )
219 {
220 throw new ScmException( "Could not detect the current branch. Don't know where I should push to!" );
221 }
222
223 cl.createArg().setValue( repository.getPushUrl() );
224
225 cl.createArg().setValue( "refs/heads/" + branch + ":" + "refs/heads/" + branch );
226
227 return cl;
228 }
229
230 public static Commandline createCommitCommandLine( GitScmProviderRepository repository, ScmFileSet fileSet,
231 File messageFile )
232 throws ScmException
233 {
234 Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "commit" );
235
236 cl.createArg().setValue( "--verbose" );
237
238 cl.createArg().setValue( "-F" );
239
240 cl.createArg().setValue( messageFile.getAbsolutePath() );
241
242 if ( fileSet.getFileList().isEmpty() )
243 {
244
245 cl.createArg().setValue( "-a" );
246 }
247 else
248 {
249
250 GitCommandLineUtils.addTarget( cl, fileSet.getFileList() );
251 }
252
253 if ( GitUtil.getSettings().isCommitNoVerify() )
254 {
255 cl.createArg().setValue( "--no-verify" );
256 }
257
258 return cl;
259 }
260
261 }