1 package org.apache.maven.scm.provider.git.command.diff;
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.ScmFile;
23 import org.apache.maven.scm.ScmFileStatus;
24 import org.apache.maven.scm.util.AbstractConsumer;
25
26 import java.io.File;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34
35
36
37
38
39
40 public class GitDiffConsumer
41 extends AbstractConsumer
42 {
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 private static final Pattern DIFF_FILES_PATTERN = Pattern.compile( "^diff --git\\sa/(.*)\\sb/(.*)" );
59
60 private static final String START_REVISION_TOKEN = "---";
61
62 private static final String END_REVISION_TOKEN = "+++";
63
64 private static final String ADDED_LINE_TOKEN = "+";
65
66 private static final String REMOVED_LINE_TOKEN = "-";
67
68 private static final String UNCHANGED_LINE_TOKEN = " ";
69
70 private static final String CHANGE_SEPARATOR_TOKEN = "@@";
71
72 private static final String NO_NEWLINE_TOKEN = "\\ No newline at end of file";
73
74 private static final String INDEX_LINE_TOKEN = "index ";
75
76 private static final String SIMILARITY_INDEX_LINE_TOKEN = "similarity index ";
77
78 private static final String RENAME_FROM_LINE_TOKEN = "rename from ";
79
80 private static final String RENAME_TO_LINE_TOKEN = "rename to ";
81
82 private static final String NEW_FILE_MODE_TOKEN = "new file mode ";
83
84 private static final String DELETED_FILE_MODE_TOKEN = "deleted file mode ";
85
86 private String currentFile;
87
88 private StringBuilder currentDifference;
89
90 private final List<ScmFile> changedFiles = new ArrayList<>();
91
92 private final Map<String, CharSequence> differences = new HashMap<>();
93
94 private final StringBuilder patch = new StringBuilder();
95
96
97
98
99
100 public GitDiffConsumer( File workingDirectory )
101 {
102
103 }
104
105
106
107
108
109
110 public void consumeLine( String line )
111 {
112 Matcher matcher = DIFF_FILES_PATTERN.matcher( line );
113 if ( matcher.matches() )
114 {
115
116 currentFile = matcher.group( 1 );
117
118 changedFiles.add( new ScmFile( currentFile, ScmFileStatus.MODIFIED ) );
119
120 currentDifference = new StringBuilder();
121
122 differences.put( currentFile, currentDifference );
123
124 patch.append( line ).append( "\n" );
125
126 return;
127 }
128
129 if ( currentFile == null )
130 {
131 if ( logger.isWarnEnabled() )
132 {
133 logger.warn( "Unparseable line: '" + line + "'" );
134 }
135 patch.append( line ).append( "\n" );
136 return;
137 }
138 else if ( line.startsWith( INDEX_LINE_TOKEN ) )
139 {
140
141 patch.append( line ).append( "\n" );
142 }
143 else if ( line.startsWith( NEW_FILE_MODE_TOKEN ) || line.startsWith( DELETED_FILE_MODE_TOKEN ) )
144 {
145
146 patch.append( line ).append( "\n" );
147 }
148 else if ( line.startsWith( START_REVISION_TOKEN ) )
149 {
150
151 patch.append( line ).append( "\n" );
152 }
153 else if ( line.startsWith( END_REVISION_TOKEN ) )
154 {
155
156 patch.append( line ).append( "\n" );
157 }
158 else if ( line.startsWith( SIMILARITY_INDEX_LINE_TOKEN ) )
159 {
160
161 patch.append( line ).append( "\n" );
162 }
163 else if ( line.startsWith( RENAME_FROM_LINE_TOKEN ) || line.startsWith( RENAME_TO_LINE_TOKEN ) )
164 {
165
166 patch.append( line ).append( "\n" );
167 }
168 else if ( line.startsWith( ADDED_LINE_TOKEN ) || line.startsWith( REMOVED_LINE_TOKEN )
169 || line.startsWith( UNCHANGED_LINE_TOKEN ) || line.startsWith( CHANGE_SEPARATOR_TOKEN )
170 || line.equals( NO_NEWLINE_TOKEN ) )
171 {
172
173 currentDifference.append( line ).append( "\n" );
174 patch.append( line ).append( "\n" );
175 }
176 else
177 {
178
179
180 if ( logger.isWarnEnabled() )
181 {
182 logger.warn( "Unparseable line: '" + line + "'" );
183 }
184 patch.append( line ).append( "\n" );
185
186 currentFile = null;
187 currentDifference = null;
188 }
189 }
190
191 public List<ScmFile> getChangedFiles()
192 {
193 return changedFiles;
194 }
195
196 public Map<String, CharSequence> getDifferences()
197 {
198 return differences;
199 }
200
201 public String getPatch()
202 {
203 return patch.toString();
204 }
205
206 }