Skip to content

Commit c0a6398

Browse files
cross-ciscoVladimir Kotal
authored andcommitted
Perforce incremental history (#2769)
1 parent 8909fd3 commit c0a6398

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/history/PerforceHistoryParser.java

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@
3232
import java.util.Calendar;
3333
import java.util.Date;
3434
import java.util.List;
35+
import java.util.logging.Level;
36+
import java.util.logging.Logger;
3537
import java.util.regex.Matcher;
3638
import java.util.regex.Pattern;
3739

40+
import org.opengrok.indexer.logger.LoggerFactory;
3841
import org.opengrok.indexer.util.Executor;
3942
import static org.opengrok.indexer.history.PerforceRepository.protectPerforceFilename;
4043

@@ -44,16 +47,22 @@
4447
* @author Emilio Monti - [email protected]
4548
*/
4649
public class PerforceHistoryParser {
50+
private static final Logger LOGGER = LoggerFactory.getLogger(PerforceHistoryParser.class);
51+
52+
History parse(File file, Repository repos) throws HistoryException {
53+
return this.parse(file, null, repos);
54+
}
4755

4856
/**
4957
* Parse the history for the specified file.
5058
*
5159
* @param file the file to parse history for
60+
* @param sinceRevision the revision before the start of desired history
5261
* @param repos Pointer to the {@code PerforceRepository}
5362
* @return object representing the file's history
5463
* @throws HistoryException if a problem occurs while executing p4 command
5564
*/
56-
History parse(File file, Repository repos) throws HistoryException {
65+
History parse(File file, String sinceRevision, Repository repos) throws HistoryException {
5766
History history;
5867

5968
if (!PerforceRepository.isInP4Depot(file, false)) {
@@ -62,9 +71,16 @@ History parse(File file, Repository repos) throws HistoryException {
6271

6372
try {
6473
if (file.isDirectory()) {
74+
/* TODO: Do I need to think about revisions here? */
6575
history = parseDirectory(file);
6676
} else {
67-
history = getRevisions(file, null);
77+
if (sinceRevision == null || "".equals(sinceRevision)) {
78+
/* Get all revisions */
79+
history = getRevisions(file, null);
80+
} else {
81+
/* Get revisions between specified and head */
82+
history = getRevisionsSince(file, sinceRevision);
83+
}
6884
}
6985
} catch (IOException ioe) {
7086
throw new HistoryException(ioe);
@@ -84,6 +100,13 @@ private History parseDirectory(File file) throws IOException {
84100
return parseChanges(executor.getOutputReader());
85101
}
86102

103+
/**
104+
* Retrieve the history of a given file.
105+
*
106+
* @param file the file to parse history for
107+
* @param rev the revision at which to end history
108+
* @return object representing the file's history
109+
*/
87110
public static History getRevisions(File file, String rev) throws IOException {
88111
ArrayList<String> cmd = new ArrayList<String>();
89112
cmd.add("p4");
@@ -96,6 +119,41 @@ public static History getRevisions(File file, String rev) throws IOException {
96119
return parseFileLog(executor.getOutputReader());
97120
}
98121

122+
/**
123+
* Retrieve the history of a given file, beginning after the specified
124+
* revision.
125+
*
126+
* @param file the file to parse history for
127+
* @param rev the revision before the start of desired history
128+
* @return object representing the file's history
129+
*/
130+
public static History getRevisionsSince(File file, String rev) throws IOException {
131+
ArrayList<String> cmd = new ArrayList<String>();
132+
cmd.add("p4");
133+
cmd.add("filelog");
134+
cmd.add("-lti");
135+
/* Okay. This is a little cheeky. getRevisionCmd(String,String) gives
136+
* a range spec that _includes_ the first revision. But, we don't want
137+
* that in this case here. So, presume that "rev" is always an integer
138+
* for perforce, add one to it, then convert back into a string to
139+
* pass into getRevisionCmd as a starting revision. */
140+
try {
141+
Integer irev = Integer.parseInt(rev);
142+
irev += 1;
143+
rev = irev.toString();
144+
} catch (NumberFormatException e) {
145+
LOGGER.log(Level.WARNING,
146+
"Unable to increment revision {}, NumberFormatException",
147+
new Object[]{rev});
148+
/* Move along with rev unchanged... */
149+
}
150+
cmd.add(file.getName() + PerforceRepository.getRevisionCmd(rev, "now"));
151+
Executor executor = new Executor(cmd, file.getCanonicalFile().getParentFile());
152+
executor.exec();
153+
154+
return parseFileLog(executor.getOutputReader());
155+
}
156+
99157
private static final Pattern REVISION_PATTERN = Pattern.compile("#\\d+ change (\\d+) \\S+ on (\\d{4})/(\\d{2})/(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2}) by ([^@]+)");
100158
private static final Pattern CHANGE_PATTERN = Pattern.compile("Change (\\d+) on (\\d{4})/(\\d{2})/(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2}) by ([^@]+)@\\S* '([^']*)'");
101159

opengrok-indexer/src/main/java/org/opengrok/indexer/history/PerforceRepository.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ History getHistory(File file) throws HistoryException {
219219
return new PerforceHistoryParser().parse(file, this);
220220
}
221221

222+
@Override
223+
History getHistory(File file, String sinceRevision)
224+
throws HistoryException {
225+
return new PerforceHistoryParser().parse(file, sinceRevision, this);
226+
}
227+
222228
@Override
223229
String determineParent(boolean interactive) throws IOException {
224230
return null;
@@ -229,16 +235,40 @@ String determineBranch(boolean interactive) {
229235
return null;
230236
}
231237
/**
232-
* Parse internal rev number and returns it in format suitable for P4 command-line.
238+
* Parse internal rev number and return it in a format suitable for P4 command-line.
233239
* @param rev Internal rev number.
234240
* @return rev number formatted for P4 command-line.
235241
*/
236242
public static String getRevisionCmd(String rev) {
237-
if(rev == null || "".equals(rev)) {
243+
if (rev == null || "".equals(rev)) {
238244
return "";
239245
}
240246
return "@" + rev;
241247
}
248+
/**
249+
* Parse rev numbers and return it as a range in a format suitable for P4 command-line.
250+
* @param first First revision number.
251+
* @param last Last revision number.
252+
* @return rev number formatted for P4 command-line.
253+
*/
254+
public static String getRevisionCmd(String first, String last) {
255+
if ((first == null || "".equals(first)) &&
256+
((last == null) || "".equals(last))) {
257+
return "";
258+
}
259+
String ret = "@";
260+
if (first == null || "".equals(first)) {
261+
ret += "0,";
262+
} else {
263+
ret += first + ",";
264+
}
265+
if (last == null || "".equals(last)) {
266+
ret += "now";
267+
} else {
268+
ret += last;
269+
}
270+
return ret;
271+
}
242272

243273
@Override
244274
String determineCurrentVersion(boolean interactive) throws IOException {

0 commit comments

Comments
 (0)