Skip to content

Commit 58fe41a

Browse files
author
Vladimir Kotal
authored
Merge pull request #1345 from tulinkry/git-renamed
Git handling renamed files
2 parents 3c3a0f7 + b1f0634 commit 58fe41a

28 files changed

+610
-143
lines changed

opengrok-indexer/build.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ information: Portions Copyright [yyyy] [name of copyright owner]
1818
1919
CDDL HEADER END
2020
21-
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
21+
Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
2222
2323
-->
2424
<project name="OpenGrok" default="jar" basedir=".">
@@ -121,7 +121,7 @@ Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
121121
defaultexcludes="no"/>
122122
<zip destfile="${build.test.classes.dir}/org/opensolaris/opengrok/history/repositories.zip"
123123
basedir="${test.repositories}"
124-
excludes="mercurial/hg/**, mercurial/hgignore, git/git"
124+
excludes="mercurial/hg/**, mercurial/hgignore, git/git/**"
125125
update="false"
126126
defaultexcludes="no"/>
127127

src/org/opensolaris/opengrok/history/GitHistoryParser.java

Lines changed: 103 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@
2828
import java.io.FileNotFoundException;
2929
import java.io.IOException;
3030
import java.io.InputStream;
31+
import java.io.InputStreamReader;
3132
import java.text.DateFormat;
3233
import java.text.ParseException;
3334
import java.util.ArrayList;
34-
import java.util.logging.Level;
35+
import java.util.List;
3536
import java.util.logging.Logger;
36-
37+
import java.util.regex.Pattern;
3738
import org.opensolaris.opengrok.configuration.RuntimeEnvironment;
3839
import org.opensolaris.opengrok.logger.LoggerFactory;
3940
import org.opensolaris.opengrok.util.Executor;
@@ -51,8 +52,8 @@ private enum ParseState {
5152
HEADER, MESSAGE, FILES
5253
}
5354
private String myDir;
54-
private History history;
5555
private GitRepository repository = new GitRepository();
56+
private List<HistoryEntry> entries = new ArrayList<>();
5657

5758
/**
5859
* Process the output from the log command and insert the HistoryEntries
@@ -70,10 +71,8 @@ public void processStream(InputStream input) throws IOException {
7071

7172
private void process(BufferedReader in) throws IOException {
7273
DateFormat df = repository.getDateFormat();
73-
ArrayList<HistoryEntry> entries = new ArrayList<HistoryEntry>();
7474
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
75-
76-
history = new History();
75+
entries = new ArrayList<>();
7776
HistoryEntry entry = null;
7877
ParseState state = ParseState.HEADER;
7978
String s = in.readLine();
@@ -142,36 +141,50 @@ private void process(BufferedReader in) throws IOException {
142141
if (entry != null) {
143142
entries.add(entry);
144143
}
145-
146-
history.setHistoryEntries(entries);
147144
}
148145

149146
/**
150147
* Parse the history for the specified file.
151148
*
152149
* @param file the file to parse history for
153-
* @param repos Pointer to the SubversionReporitory
150+
* @param repos Pointer to the GitRepository
154151
* @param sinceRevision the oldest changeset to return from the executor, or
155152
* {@code null} if all changesets should be returned
156153
* @return object representing the file's history
157154
*/
158155
History parse(File file, Repository repos, String sinceRevision) throws HistoryException {
159156
myDir = repos.getDirectoryName() + File.separator;
160157
repository = (GitRepository) repos;
158+
RenamedFilesParser parser = new RenamedFilesParser();
161159
try {
162160
Executor executor = repository.getHistoryLogExecutor(file, sinceRevision);
163161
int status = executor.exec(true, this);
164162

165163
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+
}
168180
}
169181
} 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);
172185
}
173186

174-
return history;
187+
return new History(entries, parser.getRenamedFiles());
175188
}
176189

177190
/**
@@ -184,6 +197,81 @@ History parse(File file, Repository repos, String sinceRevision) throws HistoryE
184197
History parse(String buffer) throws IOException {
185198
myDir = RuntimeEnvironment.getInstance().getSourceRootPath();
186199
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+
}
188276
}
189277
}

0 commit comments

Comments
 (0)