Skip to content

Commit 068d74d

Browse files
author
Vladimir Kotal
committed
convert findOriginalName() to JGit
1 parent b29f860 commit 068d74d

File tree

2 files changed

+45
-56
lines changed

2 files changed

+45
-56
lines changed

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

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package org.opengrok.indexer.history;
2626

27-
import java.io.BufferedReader;
2827
import java.io.File;
2928
import java.io.IOException;
3029
import java.io.InputStream;
@@ -37,7 +36,6 @@
3736
import java.util.HashSet;
3837
import java.util.List;
3938
import java.util.ArrayList;
40-
import java.util.Arrays;
4139
import java.util.HashMap;
4240
import java.util.Map;
4341
import java.util.Set;
@@ -52,8 +50,6 @@
5250
import java.util.function.Consumer;
5351
import java.util.logging.Level;
5452
import java.util.logging.Logger;
55-
import java.util.regex.Matcher;
56-
import java.util.regex.Pattern;
5753

5854
import org.eclipse.jgit.api.BlameCommand;
5955
import org.eclipse.jgit.api.Git;
@@ -283,17 +279,17 @@ private String getPathRelativeToCanonicalRepositoryRoot(String fullpath)
283279
}
284280

285281
/**
286-
* Get the name of file in given revision. The returned file name is relative
287-
* to the repository root.
282+
* Get the name of file in given revision. The returned file name is relative to the repository root.
283+
* Assumes renamed file hanndling is on.
288284
*
289-
* @param fullpath file path
290-
* @param changeset changeset
285+
* @param fullpath full file path
286+
* @param changeset revision ID (could be short)
291287
* @return original filename relative to the repository root
292288
* @throws java.io.IOException if I/O exception occurred
293289
* @see #getPathRelativeToCanonicalRepositoryRoot(String)
294290
*/
295-
String findOriginalName(String fullpath, String changeset)
296-
throws IOException {
291+
String findOriginalName(String fullpath, String changeset) throws IOException {
292+
297293
if (fullpath == null || fullpath.isEmpty()) {
298294
throw new IOException(String.format("Invalid file path string: %s", fullpath));
299295
}
@@ -303,63 +299,57 @@ String findOriginalName(String fullpath, String changeset)
303299
fullpath, changeset));
304300
}
305301

306-
String fileInRepo = getPathRelativeToCanonicalRepositoryRoot(fullpath);
307-
308-
/*
309-
* Get the list of file renames for given file to the specified
310-
* revision.
311-
*/
312-
String[] argv = {
313-
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK),
314-
"log",
315-
"--follow",
316-
"--summary",
317-
ABBREV_LOG,
318-
"--abbrev-commit",
319-
"--name-status",
320-
"--pretty=format:commit %h%n%d",
321-
"--",
322-
fileInRepo
323-
};
324-
325-
Executor executor = new Executor(Arrays.asList(argv), new File(getDirectoryName()),
326-
RuntimeEnvironment.getInstance().getInteractiveCommandTimeout());
327-
int status = executor.exec();
328-
329-
String originalFile = null;
330-
try (BufferedReader in = new BufferedReader(newLogReader(executor.getOutputStream()))) {
331-
String line;
332-
String rev = null;
333-
Matcher m;
334-
Pattern pattern = Pattern.compile("^R\\d+\\s(.*)\\s(.*)");
335-
while ((line = in.readLine()) != null) {
336-
if (line.startsWith("commit ")) {
337-
rev = line.substring(7);
302+
String fileInRepo = getGitFilePath(getPathRelativeToCanonicalRepositoryRoot(fullpath));
303+
304+
String originalFile = fileInRepo;
305+
try (org.eclipse.jgit.lib.Repository repository = getJGitRepository(getDirectoryName());
306+
RevWalk walk = new RevWalk(repository)) {
307+
308+
walk.markStart(walk.parseCommit(repository.resolve(Constants.HEAD)));
309+
walk.markUninteresting(walk.lookupCommit(repository.resolve(changeset)));
310+
311+
Config config = repository.getConfig();
312+
config.setBoolean("diff", null, "renames", true);
313+
org.eclipse.jgit.diff.DiffConfig dc = config.get(org.eclipse.jgit.diff.DiffConfig.KEY);
314+
FollowFilter followFilter = FollowFilter.create(getGitFilePath(fileInRepo), dc);
315+
walk.setTreeFilter(followFilter);
316+
317+
for (RevCommit commit : walk) {
318+
if (commit.getParentCount() > 1 && !isMergeCommitsEnabled()) {
338319
continue;
339320
}
340321

341-
if (changeset.equals(rev)) {
342-
if (originalFile == null) {
343-
originalFile = fileInRepo;
344-
}
322+
if (commit.getId().getName().startsWith(changeset)) {
345323
break;
346324
}
347325

348-
if ((m = pattern.matcher(line)).find()) {
349-
// git output paths with forward slashes so transform it if needed
350-
originalFile = Paths.get(m.group(1)).toString();
326+
if (commit.getParentCount() >= 1) {
327+
OutputStream outputStream = NullOutputStream.INSTANCE;
328+
try (DiffFormatter formatter = new DiffFormatter(outputStream)) {
329+
formatter.setRepository(repository);
330+
formatter.setDetectRenames(true);
331+
332+
List<DiffEntry> diffs = formatter.scan(prepareTreeParser(repository, commit.getParent(0)),
333+
prepareTreeParser(repository, commit));
334+
335+
for (DiffEntry diff : diffs) {
336+
if (diff.getChangeType() == DiffEntry.ChangeType.RENAME &&
337+
originalFile.equals(diff.getNewPath())) {
338+
originalFile = diff.getOldPath();
339+
}
340+
}
341+
}
351342
}
352343
}
353344
}
354345

355-
if (status != 0 || originalFile == null) {
356-
LOGGER.log(Level.WARNING,
357-
"Failed to get original name in revision {2} for: \"{0}\" Exit code: {1}",
358-
new Object[]{fullpath, String.valueOf(status), changeset});
346+
if (originalFile == null) {
347+
LOGGER.log(Level.WARNING, "Failed to get original name in revision {0} for: \"{1}\"",
348+
new Object[]{changeset, fullpath});
359349
return null;
360350
}
361351

362-
return originalFile;
352+
return getNativePath(originalFile);
363353
}
364354

365355
/**

opengrok-indexer/src/test/java/org/opengrok/indexer/history/GitRepositoryTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,7 @@ private void runRenamedTest(String fname, String cset, String content) throws Ex
501501
GitRepository gitrepo = (GitRepository) RepositoryFactory.getRepository(root);
502502
byte[] buffer = new byte[4096];
503503

504-
InputStream input = gitrepo.getHistoryGet(root.getCanonicalPath(),
505-
fname, cset);
504+
InputStream input = gitrepo.getHistoryGet(root.getCanonicalPath(), fname, cset);
506505
if (content == null) {
507506
assertNull(input, String.format("Expecting the revision %s for file %s does not exist", cset, fname));
508507
} else {

0 commit comments

Comments
 (0)