@CheckForNull
  @Override
  public Map<Path, Set<Integer>> branchChangedLines(String targetBranchName, Path projectBaseDir, Set<Path> changedFiles) {
    return branchChangedLinesWithFileMovementDetection(targetBranchName, projectBaseDir, toChangedFileByPathsMap(changedFiles));
  }
@Test
  public void branchChangedLines_given2NestedSubmodulesWithChangesInTheBottomSubmodule_detectChanges() throws IOException, GitAPIException {
    Git gitForRepo2, gitForRepo3;
    Path worktreeForRepo2, worktreeForRepo3;

    worktreeForRepo2 = temp.newFolder().toPath();
    gitForRepo2 = createRepository(worktreeForRepo2);

    worktreeForRepo3 = temp.newFolder().toPath();
    gitForRepo3 = createRepository(worktreeForRepo3);

    createAndCommitFile("sub2.js", gitForRepo3, worktreeForRepo3);

    addSubmodule(gitForRepo2, "sub2", worktreeForRepo3.toUri().toString());
    addSubmodule(git, "sub1", worktreeForRepo2.toUri().toString());

    File mainFolderWithAllSubmodules = temp.newFolder().toPath().toRealPath(LinkOption.NOFOLLOW_LINKS).toFile();
    Git.cloneRepository()
      .setURI(worktree.toUri().toString())
      .setDirectory(mainFolderWithAllSubmodules)
      .setCloneSubmodules(true)
      .call();
    Path submodule2Path = mainFolderWithAllSubmodules.toPath().resolve("sub1/sub2");
    Repository submodule2 = new RepositoryBuilder().findGitDir(submodule2Path.toFile()).build();
    Git gitForSubmodule2 = new Git(submodule2);

    gitForSubmodule2.branchCreate().setName("develop").call();
    gitForSubmodule2.checkout().setName("develop").call();

    Path submodule2File = mainFolderWithAllSubmodules.toPath().resolve("sub1/sub2/sub2.js");

    Files.write(submodule2File, randomizedContent("sub2.js", 3).getBytes(), StandardOpenOption.APPEND);
    gitForSubmodule2.add().addFilepattern("sub2.js").call();
    gitForSubmodule2.commit().setAuthor("joe", "joe@example.com").setMessage("important change").call();

    Map<Path, Set<Integer>> changedLines = newScmProvider().branchChangedLines("master", submodule2Path, Set.of(submodule2File));

    assertThat(changedLines).hasSize(1);
    assertThat(changedLines.entrySet().iterator().next().getValue()).containsOnly(4, 5, 6);
  }