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