gpt4 book ai didi

java - 是否有支持 Annotate/Blame 的 Java Diff 库?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:53:53 25 4
gpt4 key购买 nike

我正在免费(开源)Java 差异库中挖掘 Google 的结果,似乎有很多这样的库(其中一些甚至可以使用通用对象,而不仅仅是字符串)。

在我浏览大量搜索结果却找不到我正在搜索的内容之前,我会先在这里问:

这些 diff 库是否支持诸如 cvs annotate 或 svn blame 之类的功能。我要

  • 将当前的 String[] 传递给一个函数
  • 继续将旧版本的 String[] 传递给一个函数,直到我用完所有它们,或者库告诉我没有原始行未被注释(最后一件事是不是必须的,但非常有用,因为检索旧版本的 String[] 非常昂贵,所以我想尽早停止)
  • 调用一个函数,它给我一个 ìnt[] 告诉我当前版本的每一行,最后一次更改的版本或者是否根本没有更改(即最后一次更改在第一个版本中)。

支持不是 String 的对象很好,但不是必须的。如果 API 不完全是那样,我想我可以接受。

如果没有,任何人都可以建议一个可扩展的差异库,可以轻松添加该功能,最好是一个愿意将该功能作为贡献的人(并且不需要在他们接受贡献之前填写大量的文书工作) ,比如 GNU 项目)?那么我会自愿(至少尝试)将其添加到那里。

最佳答案

我决定自己为 Dmitry Naumenko 的 java-diff-utils 实现它图书馆:

/*
Copyright 2010 Michael Schierl (schierlm@gmx.de)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package difflib.annotate;

import java.util.*;

import difflib.*;

/**
* Generates an annotated version of a revision based on a list of older
* revisions, like <tt>cvs annotate</tt> or <tt>svn blame</tt>.
*
* @author <a href="schierlm@gmx.de">Michael Schierl</a>
*
* @param <R>
* Type of the revision metadata
*/
public class Annotate<R> {

private final List<R> revisions;
private final int[] lineNumbers;
private R currentRevision;
private final List<Object> currentLines;
private final List<Integer> currentLineMap;

/**
* Creates a new annotation generator.
*
* @param revision
* Revision metadata for the revision to be annotated
* @param targetLines
* Lines of the revision to be annotated
*/
public Annotate(R revision, List<?> targetLines) {
revisions = new ArrayList<R>();
lineNumbers = new int[targetLines.size()];
currentRevision = revision;
currentLines = new ArrayList<Object>(targetLines);
currentLineMap = new ArrayList<Integer>();
for (int i = 0; i < lineNumbers.length; i++) {
lineNumbers[i] = -1;
revisions.add(null);
currentLineMap.add(i);
}
}

/**
* Check whether there are still lines that are unannotated. In that case,
* more older revisions should be retrieved and passed to the function. Note
* that as soon as you pass an empty revision, all lines will be annotated
* (with a later revision), therefore if you do not have any more revisions,
* pass an empty revision to annotate the rest of the lines.
*/
public boolean areLinesUnannotated() {
for (int i = 0; i < lineNumbers.length; i++) {
if (lineNumbers[i] == -1 || revisions.get(i) == null)
return true;
}
return false;
}

/**
* Add the previous revision and update annotation info.
*
* @param revision
* Revision metadata for this revision
* @param lines
* Lines of this revision
*/
public void addRevision(R revision, List<?> lines) {
Patch patch = DiffUtils.diff(currentLines, lines);
int lineOffset = 0; // remember number of already deleted/added lines
for (Delta d : patch.getDeltas()) {
Chunk original = d.getOriginal();
Chunk revised = d.getRevised();
int pos = original.getPosition() + lineOffset;
// delete lines
for (int i = 0; i < original.getSize(); i++) {
int origLine = currentLineMap.remove(pos);
currentLines.remove(pos);
if (origLine != -1) {
lineNumbers[origLine] = original.getPosition() + i;
revisions.set(origLine, currentRevision);
}
}
for (int i = 0; i < revised.getSize(); i++) {
currentLines.add(pos + i, revised.getLines().get(i));
currentLineMap.add(pos + i, -1);
}
lineOffset += revised.getSize() - original.getSize();
}

currentRevision = revision;
if (!currentLines.equals(lines))
throw new RuntimeException("Patch application failed");
}

/**
* Return the result of the annotation. It will be a List of the same length
* as the target revision, for which every entry states the revision where
* the line appeared last.
*/
public List<R> getAnnotatedRevisions() {
return Collections.unmodifiableList(revisions);
}

/**
* Return the result of the annotation. It will be a List of the same length
* as the target revision, for which every entry states the line number in
* the revision where the line appeared last.
*/
public int[] getAnnotatedLineNumbers() {
return (int[]) lineNumbers.clone();
}
}

我还把它发给了 Dmitry Naumenko(连同一些测试用例),以防他想要包含它。

关于java - 是否有支持 Annotate/Blame 的 Java Diff 库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4443568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com