Using the JGIT, how can I retrieve the line numbers of added/deleted lines

前端 未结 3 1209
梦谈多话
梦谈多话 2021-02-20 16:56

Assuming the following piece of code is committed to a Git repository:

int test(){
   int a = 3;
   int b = 4;
   int c = a + b;
   return c;
}

相关标签:
3条回答
  • 2021-02-20 17:38

    You need to do the difference between the A line indexes and B line indexes from the diff result:

    int linesAdded = 0;
    int linesDeleted = 0;
    int filesChanged = 0;
    try {
        repo = new FileRepository(new File("repo/.git"));
        RevWalk rw = new RevWalk(repo);
        RevCommit commit = rw.parseCommit(repo.resolve("486817d67b")); // Any ref will work here (HEAD, a sha1, tag, branch)
        RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
        DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
        df.setRepository(repo);
        df.setDiffComparator(RawTextComparator.DEFAULT);
        df.setDetectRenames(true);
        List<DiffEntry> diffs;
        diffs = df.scan(parent.getTree(), commit.getTree());
        filesChanged = diffs.size();
        for (DiffEntry diff : diffs) {
            for (Edit edit : df.toFileHeader(diff).toEditList()) {
                linesDeleted += edit.getEndA() - edit.getBeginA();
                linesAdded += edit.getEndB() - edit.getBeginB();
            }
        }
    } catch (IOException e1) {
        throw new RuntimeException(e1);
    }
    
    0 讨论(0)
  • 2021-02-20 17:55

    Just a tip for anyone who might have this problem. I did not manage to get the line numbers of the added and deleted lines but I did manage to get a string which contains only the added and deleted lines without the other lines which were not changed.

    This was simply done by adding the line:

       df.setContext(0);
    

    in the snippet I provided above right before the line

       df.format(diff);
    
    0 讨论(0)
  • 2021-02-20 17:57

    I do it this way but I don't know if it is correct

    public void linesChangeInFile(Git git, List<RevCommit> commits, String fileName, String pathRepository) {
            try {
                List<RevCommit> commitsComparer = new ArrayList<>();
                List<String> linesChange = new ArrayList<>();
    
                for (int i = 0; i < commits.size() - 1; i++) {
    
                    ObjectId commitIDOld = commits.get(i).getId();
    
                    if (Validador.isFileExistInCommit(commits.get(i), getRepository(), fileName)) {
    
                        if (i != commits.size() - 1 && !commitsComparer.contains(commits.get(i))) {
                            ObjectId commitIDNew = commits.get(i + 1);
                            commitsComparer.add(commits.get(i));
                            linesChange.add(diff(git, commitIDOld.getName(), commitIDNew.getName(), fileName));
                        }
    
                        try (final FileInputStream input = new FileInputStream(pathRepository + "\\" + fileName)) {
                            currentLines = IOUtils.readLines(input, "UTF-8").size();
                        }
                    }
    
                }
    
                Integer sumLinesAdd = 0;
                Integer sumLinesDel = 0;
                for (String lineChange : linesChange) {
                    String[] lChange = lineChange.split(";");
                    sumLinesAdd += Integer.parseInt(lChange[0]);
                    sumLinesDel += Integer.parseInt(lChange[1]);
                }
    
                System.out.println("Lines Add total:" + sumLinesAdd);
                System.out.println("Lines Del total:" + sumLinesDel);
                System.out.println("Total lines change:" + (sumLinesAdd + sumLinesDel));
    
            } catch (RevisionSyntaxException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    private String diff(Git git, String commitIDOld, String commitIDNew, String fileName) {
            int linesAdded = 0;
            int linesDeleted = 0;
            DiffFormatter df = null;
            try {
                AbstractTreeIterator oldTreeParser = prepareTreeParser(getRepository(), commitIDOld);
                AbstractTreeIterator newTreeParser = prepareTreeParser(getRepository(), commitIDNew);
    
                List<DiffEntry> diffs = git.diff().setOldTree(oldTreeParser).setNewTree(newTreeParser)
                        .setPathFilter(PathFilter.create(fileName)).call();
    
                df = new DiffFormatter(DisabledOutputStream.INSTANCE);
                df.setRepository(getRepository());
                df.setDiffComparator(RawTextComparator.DEFAULT);
                df.setDetectRenames(true);
    
                for (DiffEntry entry : diffs) {
                    // System.out.println("Entry: " + entry + ", from: " + entry.getOldId() + ", to:
                    // " + entry.getNewId());
                    // try (DiffFormatter formatter = new DiffFormatter(System.out)) {
                    // formatter.setContext(0);
                    // formatter.setRepository(repository);
                    // formatter.format(entry);
                    // }
                    for (Edit edit : df.toFileHeader(entry).toEditList()) {
                        linesDeleted += edit.getEndA() - edit.getBeginA();
                        linesAdded += edit.getEndB() - edit.getBeginB();
                    }
                }
            } catch (IOException | GitAPIException e) {
                System.err.println("Error:" + e.getMessage());
            }
    
            return linesAdded + ";" + linesDeleted;
    
        }
    
    0 讨论(0)
提交回复
热议问题