Reputation: 4053
I am using SVN kit to gather some metrics from SVN repositories. I am stuck with this simple problem and am unable to get through it.
I have an SVNRepository object that give me paths of all files in the repository and their different revisions. I want to set previous revision value for each of the revision. How can I do that without checking out that file? Or rather what is the best way to do it so as to have best performance from my code?
It should also consider the copy/paste and move activity when allotting the previous revision.
Upvotes: 2
Views: 2633
Reputation: 4053
Following technique worked for me.
//This is where I query SVN server
if (entryPath.getType() != SVNLogEntryPath.TYPE_ADDED) {
LogEntryPreviousRevFinder handler = new LogEntryPreviousRevFinder(workingFileName.substring(interestingPath.length()), thisRevision);
//Start checking for previous modified revision for this file in the previous 3 revision.
//If not found try for previous 5 and then 7. If not found till then, put in a warning and continue.
//This is necessary because in SVN a branch operation is performed at the folder level and not file
//hence we need to go further back and find out the revision than was last modified.
for (int i = 3; i <= 7; i+=2) {
repository.log(new String[] {workingFileName}, thisRevision, 0l, true, false, i, handler);
if (handler.isSuccess()) {
prevPath = handler.getPreviousPath();
prevRevision = handler.getPreviousRevision();
break;
} else {
continue;
}
}
if (!handler.isSuccess()) {
log.warn("Failed to find previous revision for file: " + workingFileName
+ " Will contine considering this one as added in this revision");
}
} else {
//Files with SVNLogEntryPath.TYPE_ADDED are either added in this revision
//or are copied or renamed from an existing file. If later, we need to identify the Copy from path
//as that will be the file which will be used for calculating relative metrics and later Flux values
if (entryPath.getCopyPath() != null && entryPath.getCopyPath().trim().length() > 0) {
prevPath = entryPath.getCopyPath();
prevRevision = entryPath.getCopyRevision();
} else {
log.debug("File: " + workingFileName + " added in this revision");
}
}
ISVNLogEntryHandler implementation:
//ISVNLogEntryHandler implementation for identifying previous revision
private class LogEntryPreviousRevFinder implements ISVNLogEntryHandler {
private String interestingFile;
private String previousPath;
private long thisRevision;
private long previousRevision;
private boolean isSuccess;
public LogEntryPreviousRevFinder(String interestingFile, long revision) {
this.interestingFile = interestingFile;
this.thisRevision = revision;
isSuccess = false;
}
@Override
public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
if (isSuccess)
return;
if (thisRevision == logEntry.getRevision())
return;
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths.hasNext();) {
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next());
String workingFileName = entryPath.getPath();
if (workingFileName.endsWith(interestingFile)) {
previousRevision = logEntry.getRevision();
previousPath = workingFileName;
isSuccess = true;
}
}
}
public long getPreviousRevision() {
return previousRevision;
}
public String getPreviousPath() {
return previousPath;
}
public boolean isSuccess() {
return isSuccess;
}
}
I wonder if there is a better and more efficient way to do this.
Upvotes: 3