Skip to content

Commit d56fc23

Browse files
author
Vladimir Kotal
committed
handle annotate when renamed file handling is off
fixes #2271
1 parent a99355d commit d56fc23

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

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

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,44 @@ protected String findOriginalName(String fullpath, String changeset)
351351
return (fullpath.substring(0, getDirectoryName().length() + 1) + file);
352352
}
353353

354+
/**
355+
* Get first revision of given file without following renames.
356+
* @param file file to get first revision of
357+
*/
358+
private String getFirstRevision(String fullpath) throws IOException {
359+
String[] argv = {
360+
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK),
361+
"rev-list",
362+
"--reverse",
363+
"--max-count=1",
364+
"HEAD",
365+
"--",
366+
fullpath
367+
};
368+
369+
Executor executor = new Executor(Arrays.asList(argv), new File(getDirectoryName()),
370+
RuntimeEnvironment.getInstance().getInteractiveCommandTimeout());
371+
int status = executor.exec();
372+
373+
try (BufferedReader in = new BufferedReader(
374+
new InputStreamReader(executor.getOutputStream()))) {
375+
String line;
376+
377+
if ((line = in.readLine()) != null) {
378+
return line.trim();
379+
}
380+
}
381+
382+
if (status != 0) {
383+
LOGGER.log(Level.WARNING,
384+
"Failed to get first revision for: \"{0}\" Exit code: {1}",
385+
new Object[]{fullpath, String.valueOf(status)});
386+
return null;
387+
}
388+
389+
return null;
390+
}
391+
354392
/**
355393
* Annotate the specified file/revision.
356394
*
@@ -369,15 +407,27 @@ public Annotation annotate(File file, String revision) throws IOException {
369407
cmd.add(ABBREV_BLAME);
370408
if (revision != null) {
371409
cmd.add(revision);
410+
} else {
411+
// {@code git blame} follows renames by default. If renamed file handling is off, its output would
412+
// contain invalid revisions. Therefore, the revision range needs to be constrained.
413+
if (!isHandleRenamedFiles()) {
414+
String firstRevision = getFirstRevision(file.getAbsolutePath());
415+
if (firstRevision == null) {
416+
return null;
417+
}
418+
cmd.add(firstRevision + "..");
419+
}
372420
}
421+
cmd.add("--");
373422
cmd.add(file.getName());
374423

375424
Executor exec = new Executor(cmd, file.getParentFile(),
376425
RuntimeEnvironment.getInstance().getInteractiveCommandTimeout());
377426
GitAnnotationParser parser = new GitAnnotationParser(file.getName());
378427
int status = exec.exec(true, parser);
379428

380-
// File might have changed its location
429+
// File might have changed its location if it was renamed.
430+
// Try to lookup its original name and get the annotation again.
381431
if (status != 0) {
382432
cmd.clear();
383433
ensureCommand(CMD_PROPERTY_KEY, CMD_FALLBACK);

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
import java.nio.file.Paths;
3333
import java.text.DateFormat;
3434
import java.text.ParseException;
35+
import java.util.Collections;
36+
import java.util.HashSet;
37+
import java.util.Set;
38+
3539
import org.junit.After;
3640
import org.junit.AfterClass;
3741
import org.junit.Assert;
@@ -200,6 +204,41 @@ public void testRenamedFiles() throws Exception {
200204
}
201205
}
202206

207+
private void testAnnotationOfRenamedFile(GitRepository gitrepo, File file, Set<String> revSet) throws Exception {
208+
Annotation annotation = gitrepo.annotate(file, null);
209+
210+
assertNotNull(annotation);
211+
assertEquals(revSet, annotation.getRevisions());
212+
}
213+
214+
@Test
215+
public void testAnnotationOfRenamedFileWithHandlingOff() throws Exception {
216+
String[] revisions = {"84599b3c"};
217+
Set<String> revSet = new HashSet<>();
218+
Collections.addAll(revSet, revisions);
219+
220+
File root = new File(repository.getSourceRoot(), "git");
221+
GitRepository gitrepo
222+
= (GitRepository) RepositoryFactory.getRepository(root);
223+
gitrepo.setHandleRenamedFiles(false);
224+
File renamedFile = Paths.get(root.getAbsolutePath(),"moved2", "renamed2.c").toFile();
225+
testAnnotationOfRenamedFile(gitrepo, renamedFile, revSet);
226+
}
227+
228+
@Test
229+
public void testAnnotationOfRenamedFileWithHandlingOn() throws Exception {
230+
String[] revisions = {"1086eaf5", "ce4c98ec"};
231+
Set<String> revSet = new HashSet<>();
232+
Collections.addAll(revSet, revisions);
233+
234+
File root = new File(repository.getSourceRoot(), "git");
235+
GitRepository gitrepo
236+
= (GitRepository) RepositoryFactory.getRepository(root);
237+
gitrepo.setHandleRenamedFiles(true);
238+
File renamedFile = Paths.get(root.getAbsolutePath(),"moved2", "renamed2.c").toFile();
239+
testAnnotationOfRenamedFile(gitrepo, renamedFile, revSet);
240+
}
241+
203242
@Test(expected = IOException.class)
204243
public void testInvalidRenamedFiles() throws Exception {
205244
String[][] tests = new String[][]{

testdata/repositories/git/git/index

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)