28
28
import java .io .FileNotFoundException ;
29
29
import java .io .IOException ;
30
30
import java .io .InputStream ;
31
+ import java .io .InputStreamReader ;
31
32
import java .text .DateFormat ;
32
33
import java .text .ParseException ;
33
34
import java .util .ArrayList ;
34
- import java .util .logging . Level ;
35
+ import java .util .List ;
35
36
import java .util .logging .Logger ;
36
-
37
+ import java . util . regex . Pattern ;
37
38
import org .opensolaris .opengrok .configuration .RuntimeEnvironment ;
38
39
import org .opensolaris .opengrok .logger .LoggerFactory ;
39
40
import org .opensolaris .opengrok .util .Executor ;
@@ -51,8 +52,8 @@ private enum ParseState {
51
52
HEADER , MESSAGE , FILES
52
53
}
53
54
private String myDir ;
54
- private History history ;
55
55
private GitRepository repository = new GitRepository ();
56
+ private List <HistoryEntry > entries = new ArrayList <>();
56
57
57
58
/**
58
59
* Process the output from the log command and insert the HistoryEntries
@@ -70,10 +71,8 @@ public void processStream(InputStream input) throws IOException {
70
71
71
72
private void process (BufferedReader in ) throws IOException {
72
73
DateFormat df = repository .getDateFormat ();
73
- ArrayList <HistoryEntry > entries = new ArrayList <HistoryEntry >();
74
74
RuntimeEnvironment env = RuntimeEnvironment .getInstance ();
75
-
76
- history = new History ();
75
+ entries = new ArrayList <>();
77
76
HistoryEntry entry = null ;
78
77
ParseState state = ParseState .HEADER ;
79
78
String s = in .readLine ();
@@ -142,36 +141,50 @@ private void process(BufferedReader in) throws IOException {
142
141
if (entry != null ) {
143
142
entries .add (entry );
144
143
}
145
-
146
- history .setHistoryEntries (entries );
147
144
}
148
145
149
146
/**
150
147
* Parse the history for the specified file.
151
148
*
152
149
* @param file the file to parse history for
153
- * @param repos Pointer to the SubversionReporitory
150
+ * @param repos Pointer to the GitRepository
154
151
* @param sinceRevision the oldest changeset to return from the executor, or
155
152
* {@code null} if all changesets should be returned
156
153
* @return object representing the file's history
157
154
*/
158
155
History parse (File file , Repository repos , String sinceRevision ) throws HistoryException {
159
156
myDir = repos .getDirectoryName () + File .separator ;
160
157
repository = (GitRepository ) repos ;
158
+ RenamedFilesParser parser = new RenamedFilesParser ();
161
159
try {
162
160
Executor executor = repository .getHistoryLogExecutor (file , sinceRevision );
163
161
int status = executor .exec (true , this );
164
162
165
163
if (status != 0 ) {
166
- throw new HistoryException ("Failed to get history for: \" " +
167
- file .getAbsolutePath () + "\" Exit code: " + status );
164
+ throw new HistoryException (
165
+ String .format ("Failed to get history for: \" %s\" Exit code: %d" ,
166
+ file .getAbsolutePath (),
167
+ status ));
168
+ }
169
+
170
+ if (RuntimeEnvironment .getInstance ().isHandleHistoryOfRenamedFiles ()) {
171
+ executor = repository .getRenamedFilesExecutor (file , sinceRevision );
172
+ status = executor .exec (true , parser );
173
+
174
+ if (status != 0 ) {
175
+ throw new HistoryException (
176
+ String .format ("Failed to get renamed files for: \" %s\" Exit code: %d" ,
177
+ file .getAbsolutePath (),
178
+ status ));
179
+ }
168
180
}
169
181
} catch (IOException e ) {
170
- throw new HistoryException ("Failed to get history for: \" " +
171
- file .getAbsolutePath () + "\" " , e );
182
+ throw new HistoryException (
183
+ String .format ("Failed to get history for: \" %s\" " , file .getAbsolutePath ()),
184
+ e );
172
185
}
173
186
174
- return history ;
187
+ return new History ( entries , parser . getRenamedFiles ()) ;
175
188
}
176
189
177
190
/**
@@ -184,6 +197,81 @@ History parse(File file, Repository repos, String sinceRevision) throws HistoryE
184
197
History parse (String buffer ) throws IOException {
185
198
myDir = RuntimeEnvironment .getInstance ().getSourceRootPath ();
186
199
processStream (new ByteArrayInputStream (buffer .getBytes ("UTF-8" )));
187
- return history ;
200
+ return new History (entries );
201
+ }
202
+
203
+ /**
204
+ * Class for handling renamed files stream.
205
+ */
206
+ private class RenamedFilesParser implements Executor .StreamHandler {
207
+
208
+ private final List <String > renamedFiles = new ArrayList <>();
209
+
210
+ @ Override
211
+ public void processStream (InputStream input ) throws IOException {
212
+ /*
213
+ * Commands to create the git repository:
214
+ *
215
+ * $ git init
216
+ * $ touch main.c
217
+ * $ touch foo.f
218
+ * $ touch foo2.f
219
+ * $ nano main.c # - add some lines
220
+ * $ git add . && git commit -m "first"
221
+ * $ mkdir moved
222
+ * $ mv main.c moved/
223
+ * $ git add . && git commit -m "second"
224
+ * $ nano moved/main.c # - change/add some lines
225
+ * $ git add . && git commit -m "third"
226
+ * $ mv moved/main.c moved/movedmain.c
227
+ * $ git add . && git commit -m "moved main"
228
+ * $ nano moved/movedmain.c # - change/add some lines
229
+ * $ git add . && git commit -m "changing some lines"
230
+ *
231
+ *
232
+ * Expected output format for this repository:
233
+ *
234
+ * 520b0dd changing some lines
235
+ * M moved/movedmain.c
236
+ *
237
+ * 07a8318 moved main
238
+ * R100 moved/main.c moved/movedmain.c
239
+ *
240
+ * e934333 third
241
+ * M moved/main.c
242
+ *
243
+ * 1ee21eb second
244
+ * R100 main.c moved/main.c
245
+ *
246
+ * 50bb0d3 first
247
+ * A foo.f
248
+ * A foo2.f
249
+ * A main.c
250
+ */
251
+ RuntimeEnvironment env = RuntimeEnvironment .getInstance ();
252
+
253
+ try (BufferedReader in = new BufferedReader (new InputStreamReader (input ))) {
254
+ String line ;
255
+ Pattern pattern = Pattern .compile ("^R\\ d+\\ s.*" );
256
+ while ((line = in .readLine ()) != null ) {
257
+ if (pattern .matcher (line ).matches ()) {
258
+ String [] parts = line .split ("\t " );
259
+ if (parts .length < 3
260
+ || parts [1 ].length () <= 0
261
+ || renamedFiles .contains (parts [1 ])) {
262
+ continue ;
263
+ }
264
+ renamedFiles .add (parts [2 ]);
265
+ }
266
+ }
267
+ }
268
+ }
269
+
270
+ /**
271
+ * @return renamed files for this repository
272
+ */
273
+ public List <String > getRenamedFiles () {
274
+ return renamedFiles ;
275
+ }
188
276
}
189
277
}
0 commit comments