use of com.google.gerrit.server.patch.filediff.FileDiffOutput in project gerrit by GerritCodeReview.
the class DiffOperationsImpl method getModifiedFilesForKeys.
/**
* Lookup the file diffs for the input {@code keys}. For results where the cache reports negative
* results, e.g. due to timeouts in the cache loader, this method requests the diff again using
* the fallback algorithm {@link DiffAlgorithm#HISTOGRAM_NO_FALLBACK}.
*/
private ImmutableMap<String, FileDiffOutput> getModifiedFilesForKeys(List<FileDiffCacheKey> keys, DiffOptions diffOptions) throws DiffNotAvailableException {
ImmutableMap<FileDiffCacheKey, FileDiffOutput> fileDiffs = fileDiffCache.getAll(keys);
List<FileDiffCacheKey> fallbackKeys = new ArrayList<>();
ImmutableList.Builder<FileDiffOutput> result = ImmutableList.builder();
// Use the fallback diff algorithm for negative results
for (FileDiffCacheKey key : fileDiffs.keySet()) {
FileDiffOutput diff = fileDiffs.get(key);
if (diff.isNegative()) {
FileDiffCacheKey fallbackKey = createFileDiffCacheKey(key.project(), key.oldCommit(), key.newCommit(), key.newFilePath(), // Use the fallback diff algorithm
DiffAlgorithm.HISTOGRAM_NO_FALLBACK, /* useTimeout= */
false, key.whitespace());
fallbackKeys.add(fallbackKey);
} else {
result.add(diff);
}
}
result.addAll(fileDiffCache.getAll(fallbackKeys).values());
return mapByFilePath(result.build(), diffOptions);
}
use of com.google.gerrit.server.patch.filediff.FileDiffOutput in project gerrit by GerritCodeReview.
the class ChangeEmail method getUnifiedDiff.
/**
* Show patch set as unified difference.
*/
public String getUnifiedDiff() {
Map<String, FileDiffOutput> modifiedFiles;
try {
modifiedFiles = listModifiedFiles();
if (modifiedFiles.isEmpty()) {
// Currently these always have a null oldId in the PatchList.
return "[Octopus merge; cannot be formatted as a diff.]\n";
}
} catch (DiffNotAvailableException e) {
logger.atSevere().withCause(e).log("Cannot format patch");
return "";
}
int maxSize = args.settings.maximumDiffSize;
TemporaryBuffer.Heap buf = new TemporaryBuffer.Heap(Math.min(HEAP_EST_SIZE, maxSize), maxSize);
try (DiffFormatter fmt = new DiffFormatter(buf)) {
try (Repository git = args.server.openRepository(change.getProject())) {
try {
ObjectId oldId = modifiedFiles.values().iterator().next().oldCommitId();
ObjectId newId = modifiedFiles.values().iterator().next().newCommitId();
if (oldId.equals(ObjectId.zeroId())) {
// DiffOperations returns ObjectId.zeroId if newCommit is a root commit, i.e. has no
// parents.
oldId = null;
}
fmt.setRepository(git);
fmt.setDetectRenames(true);
fmt.format(oldId, newId);
return RawParseUtils.decode(buf.toByteArray());
} catch (IOException e) {
if (JGitText.get().inMemoryBufferLimitExceeded.equals(e.getMessage())) {
return "";
}
logger.atSevere().withCause(e).log("Cannot format patch");
return "";
}
} catch (IOException e) {
logger.atSevere().withCause(e).log("Cannot open repository to format patch");
return "";
}
}
}
use of com.google.gerrit.server.patch.filediff.FileDiffOutput in project gerrit by GerritCodeReview.
the class FileInfoJsonImpl method asFileInfo.
private Map<String, FileInfo> asFileInfo(Map<String, FileDiffOutput> fileDiffs) {
Map<String, FileInfo> result = new HashMap<>();
for (String path : fileDiffs.keySet()) {
FileDiffOutput fileDiff = fileDiffs.get(path);
FileInfo fileInfo = new FileInfo();
fileInfo.status = fileDiff.changeType() != Patch.ChangeType.MODIFIED ? fileDiff.changeType().getCode() : null;
fileInfo.oldPath = FilePathAdapter.getOldPath(fileDiff.oldPath(), fileDiff.changeType());
fileInfo.sizeDelta = fileDiff.sizeDelta();
fileInfo.size = fileDiff.size();
if (fileDiff.patchType().get() == Patch.PatchType.BINARY) {
fileInfo.binary = true;
} else {
fileInfo.linesInserted = fileDiff.insertions() > 0 ? fileDiff.insertions() : null;
fileInfo.linesDeleted = fileDiff.deletions() > 0 ? fileDiff.deletions() : null;
}
result.put(path, fileInfo);
}
return result;
}
use of com.google.gerrit.server.patch.filediff.FileDiffOutput in project gerrit by GerritCodeReview.
the class FileEditsPredicate method match.
@Override
public boolean match(ChangeData cd) {
try {
Map<String, FileDiffOutput> modifiedFiles = diffOperations.listModifiedFilesAgainstParent(cd.project(), cd.currentPatchSet().commitId(), /* parentNum= */
0, DiffOptions.DEFAULTS);
FileDiffOutput firstDiff = Iterables.getFirst(modifiedFiles.values(), /* defaultValue= */
null);
if (firstDiff == null) {
// engine.fail();
return false;
}
Pattern filePattern = null;
Pattern editPattern = null;
if (fileEditsArgs.filePattern().startsWith("^")) {
// We validated the pattern before creating this predicate. No need to revalidate.
String pattern = fileEditsArgs.filePattern();
filePattern = Pattern.compile(pattern);
}
if (fileEditsArgs.editPattern().startsWith("^")) {
// We validated the pattern before creating this predicate. No need to revalidate.
String pattern = fileEditsArgs.editPattern();
editPattern = Pattern.compile(pattern);
}
try (Repository repo = repoManager.openRepository(cd.project());
ObjectReader reader = repo.newObjectReader();
RevWalk rw = new RevWalk(reader)) {
RevTree aTree = firstDiff.oldCommitId().equals(ObjectId.zeroId()) ? null : rw.parseTree(firstDiff.oldCommitId());
RevTree bTree = rw.parseCommit(firstDiff.newCommitId()).getTree();
for (FileDiffOutput entry : modifiedFiles.values()) {
String newName = FilePathAdapter.getNewPath(entry.oldPath(), entry.newPath(), entry.changeType());
String oldName = FilePathAdapter.getOldPath(entry.oldPath(), entry.changeType());
if (Patch.isMagic(newName)) {
continue;
}
if (match(newName, fileEditsArgs.filePattern(), filePattern) || (oldName != null && match(oldName, fileEditsArgs.filePattern(), filePattern))) {
List<Edit> edits = entry.edits().stream().map(TaggedEdit::jgitEdit).collect(Collectors.toList());
if (edits.isEmpty()) {
continue;
}
Text tA;
if (oldName != null) {
tA = load(aTree, oldName, reader);
} else {
tA = load(aTree, newName, reader);
}
Text tB = load(bTree, newName, reader);
for (Edit edit : edits) {
if (tA != Text.EMPTY) {
String aDiff = tA.getString(edit.getBeginA(), edit.getEndA(), true);
if (match(aDiff, fileEditsArgs.editPattern(), editPattern)) {
return true;
}
}
if (tB != Text.EMPTY) {
String bDiff = tB.getString(edit.getBeginB(), edit.getEndB(), true);
if (match(bDiff, fileEditsArgs.editPattern(), editPattern)) {
return true;
}
}
}
}
}
} catch (IOException e) {
logger.atSevere().withCause(e).log("Error while evaluating commit edits.");
return false;
}
} catch (DiffNotAvailableException e) {
logger.atSevere().withCause(e).log("Diff error while evaluating commit edits.");
return false;
}
return false;
}
use of com.google.gerrit.server.patch.filediff.FileDiffOutput in project gerrit by GerritCodeReview.
the class DiffOperationsTest method diffModifiedFileAgainstParent.
@Test
public void diffModifiedFileAgainstParent() throws Exception {
ImmutableList<FileEntity> oldFiles = ImmutableList.of(new FileEntity(fileName1, fileContent1), new FileEntity(fileName2, fileContent2));
ObjectId oldCommitId = createCommit(repo, null, oldFiles);
ImmutableList<FileEntity> newFiles = ImmutableList.of(new FileEntity(fileName1, fileContent1), new FileEntity(fileName2, fileContent2 + "\nnew line here"));
ObjectId newCommitId = createCommit(repo, oldCommitId, newFiles);
FileDiffOutput diffOutput = diffOperations.getModifiedFileAgainstParent(testProjectName, newCommitId, /* parentNum=*/
0, fileName2, /* whitespace=*/
null);
assertThat(diffOutput.oldCommitId()).isEqualTo(oldCommitId);
assertThat(diffOutput.newCommitId()).isEqualTo(newCommitId);
assertThat(diffOutput.comparisonType().isAgainstParent()).isTrue();
assertThat(diffOutput.edits()).hasSize(1);
}
Aggregations