use of org.eclipse.jgit.diff.DiffEntry in project egit by eclipse.
the class GitDocument method populate.
void populate() throws IOException {
if (GitTraceLocation.QUICKDIFF.isActive())
GitTraceLocation.getTrace().traceEntry(GitTraceLocation.QUICKDIFF.getLocation(), resource);
// Do not populate if already disposed
if (disposed)
return;
RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
if (mapping == null) {
// $NON-NLS-1$
setResolved(null, null, null, "");
return;
}
final String gitPath = mapping.getRepoRelativePath(resource);
if (gitPath == null) {
// $NON-NLS-1$
setResolved(null, null, null, "");
return;
}
final Repository repository = mapping.getRepository();
String baseline = GitQuickDiffProvider.baseline.get(repository);
if (baseline == null)
baseline = Constants.HEAD;
ObjectId commitId = repository.resolve(baseline);
if (commitId != null) {
if (commitId.equals(lastCommit)) {
if (GitTraceLocation.QUICKDIFF.isActive())
GitTraceLocation.getTrace().trace(GitTraceLocation.QUICKDIFF.getLocation(), // $NON-NLS-1$
"(GitDocument) already resolved");
return;
}
} else {
if (repository.exactRef(Constants.HEAD) == null) {
// Complain only if not an unborn branch
String msg = NLS.bind(UIText.GitDocument_errorResolveQuickdiff, new Object[] { baseline, resource, repository });
Activator.logError(msg, new Throwable());
}
// $NON-NLS-1$
setResolved(null, null, null, "");
return;
}
RevCommit baselineCommit;
String oldPath = gitPath;
try (RevWalk rw = new RevWalk(repository);
ObjectReader reader = repository.newObjectReader()) {
baselineCommit = rw.parseCommit(commitId);
DiffConfig diffConfig = repository.getConfig().get(DiffConfig.KEY);
if (diffConfig.getRenameDetectionType() != RenameDetectionType.FALSE) {
TreeWalk walk = new TreeWalk(repository);
CanonicalTreeParser baseLineIterator = new CanonicalTreeParser();
baseLineIterator.reset(reader, baselineCommit.getTree());
walk.addTree(baseLineIterator);
walk.addTree(new DirCacheIterator(repository.readDirCache()));
List<DiffEntry> diffs = DiffEntry.scan(walk, true);
RenameDetector renameDetector = new RenameDetector(repository);
renameDetector.addAll(diffs);
List<DiffEntry> renames = renameDetector.compute();
for (DiffEntry e : renames) {
if (e.getNewPath().equals(gitPath)) {
oldPath = e.getOldPath();
break;
}
}
}
} catch (IOException err) {
String msg = NLS.bind(UIText.GitDocument_errorLoadCommit, new Object[] { commitId, baseline, resource, repository });
Activator.logError(msg, err);
// $NON-NLS-1$
setResolved(null, null, null, "");
return;
}
RevTree treeId = baselineCommit.getTree();
if (treeId.equals(lastTree)) {
if (GitTraceLocation.QUICKDIFF.isActive())
GitTraceLocation.getTrace().trace(GitTraceLocation.QUICKDIFF.getLocation(), // $NON-NLS-1$
"(GitDocument) already resolved");
return;
}
try (TreeWalk tw = TreeWalk.forPath(repository, oldPath, treeId)) {
if (tw == null) {
if (GitTraceLocation.QUICKDIFF.isActive())
GitTraceLocation.getTrace().trace(GitTraceLocation.QUICKDIFF.getLocation(), // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"(GitDocument) resource " + resource + " not found in " + treeId + " in " + repository + ", baseline=" + baseline);
// $NON-NLS-1$
setResolved(null, null, null, "");
return;
}
ObjectId id = tw.getObjectId(0);
if (id.equals(ObjectId.zeroId())) {
// $NON-NLS-1$
setResolved(null, null, null, "");
String msg = NLS.bind(UIText.GitDocument_errorLoadTree, new Object[] { treeId.getName(), baseline, resource, repository });
Activator.logError(msg, new Throwable());
// $NON-NLS-1$
setResolved(null, null, null, "");
return;
}
if (!id.equals(lastBlob)) {
if (GitTraceLocation.QUICKDIFF.isActive())
GitTraceLocation.getTrace().trace(GitTraceLocation.QUICKDIFF.getLocation(), // $NON-NLS-1$
"(GitDocument) compareTo: " + baseline);
ObjectLoader loader = repository.open(id, Constants.OBJ_BLOB);
byte[] bytes = loader.getBytes();
String charset;
charset = CompareCoreUtils.getResourceEncoding(resource);
// Finally we could consider validating the content with respect
// to the content. We don't do that here.
String s = new String(bytes, charset);
setResolved(commitId, treeId, id, s);
if (GitTraceLocation.QUICKDIFF.isActive())
GitTraceLocation.getTrace().trace(GitTraceLocation.QUICKDIFF.getLocation(), // $NON-NLS-1$ //$NON-NLS-2$
"(GitDocument) has reference doc, size=" + s.length() + " bytes");
} else {
if (GitTraceLocation.QUICKDIFF.isActive())
GitTraceLocation.getTrace().trace(GitTraceLocation.QUICKDIFF.getLocation(), // $NON-NLS-1$
"(GitDocument) already resolved");
}
} finally {
if (GitTraceLocation.QUICKDIFF.isActive()) {
GitTraceLocation.getTrace().traceExit(GitTraceLocation.QUICKDIFF.getLocation());
}
}
}
use of org.eclipse.jgit.diff.DiffEntry in project egit by eclipse.
the class BlameInformationControl method createDiffLinkAndText.
private void createDiffLinkAndText(final RevCommit parent, final Diff diff) throws IOException {
String parentId = parent.toObjectId().abbreviate(7).name();
String parentMessage = parent.getShortMessage();
EditList interestingDiff = getInterestingDiff(diff.getEditList());
final Integer parentLine;
if (!interestingDiff.isEmpty())
parentLine = Integer.valueOf(interestingDiff.get(0).getBeginA());
else
parentLine = null;
Composite header = new Composite(diffComposite, SWT.NONE);
header.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());
Label diffHeaderLabel = new Label(header, SWT.NONE);
diffHeaderLabel.setText(NLS.bind(UIText.BlameInformationControl_DiffHeaderLabel, parentId, parentMessage));
showAnnotationsLink = new Link(header, SWT.NONE);
showAnnotationsLink.setText(UIText.BlameInformationControl_ShowAnnotationsLink);
showAnnotationsLinkSelectionAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
blameParent(parent, diff, parentLine);
}
};
showAnnotationsLink.addSelectionListener(showAnnotationsLinkSelectionAdapter);
DiffViewer diffText = new DiffViewer(diffComposite, null, SWT.NONE);
diffText.configure(new DiffViewer.Configuration(EditorsUI.getPreferenceStore()));
diffText.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
DiffDocument document = new DiffDocument();
try (DiffRegionFormatter diffFormatter = new DiffRegionFormatter(document)) {
diffFormatter.setContext(1);
diffFormatter.setRepository(revision.getRepository());
diffFormatter.format(interestingDiff, diff.getOldText(), diff.getNewText());
try (ObjectReader reader = revision.getRepository().newObjectReader()) {
DiffEntry diffEntry = CompareCoreUtils.getChangeDiffEntry(revision.getRepository(), revision.getSourcePath(), revision.getCommit(), parent, reader);
if (diffEntry != null) {
FileDiff fileDiff = new FileDiff(revision.getCommit(), diffEntry);
document.setDefault(revision.getRepository(), fileDiff);
}
}
document.connect(diffFormatter);
}
diffText.setDocument(document);
}
use of org.eclipse.jgit.diff.DiffEntry in project fuse-karaf by jboss-fuse.
the class GitConflictResolutionIT method reportingDiffs.
@Test
public void reportingDiffs() throws Exception {
prepareChanges();
ObjectReader reader = git.getRepository().newObjectReader();
RevWalk rw = new RevWalk(git.getRepository());
CanonicalTreeParser ctp1 = new CanonicalTreeParser();
CanonicalTreeParser ctp2 = new CanonicalTreeParser();
CanonicalTreeParser ctp3 = new CanonicalTreeParser();
ctp1.reset(reader, rw.parseCommit(git.getRepository().resolve("master")).getTree());
ctp2.reset(reader, rw.parseCommit(git.getRepository().resolve("custom")).getTree());
ctp3.reset(reader, rw.parseCommit(git.getRepository().resolve("patched")).getTree());
TreeWalk walk = new TreeWalk(reader);
walk.addTree(ctp1);
walk.addTree(ctp3);
walk.setRecursive(true);
List<DiffEntry> diffs = DiffEntry.scan(walk);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DiffFormatter df = new DiffFormatter(baos);
df.setDiffAlgorithm(DiffAlgorithm.getAlgorithm(DiffAlgorithm.SupportedAlgorithm.HISTOGRAM));
df.setDiffComparator(RawTextComparator.DEFAULT);
df.setRepository(git.getRepository());
df.format(diffs.get(0));
// System.out.println(new String(baos.toByteArray()));
AbbreviatedObjectId id1 = diffs.get(0).getOldId();
AbbreviatedObjectId id2 = diffs.get(0).getNewId();
byte[] bytes1 = reader.open(id1.toObjectId()).getBytes();
byte[] bytes2 = reader.open(id2.toObjectId()).getBytes();
RawText rt1 = new RawText(bytes1);
RawText rt2 = new RawText(bytes2);
EditList edits = DiffAlgorithm.getAlgorithm(DiffAlgorithm.SupportedAlgorithm.HISTOGRAM).diff(RawTextComparator.DEFAULT, rt1, rt2);
int aCur = 0;
for (Edit curEdit : edits) {
boolean prolog = aCur < curEdit.getBeginA();
if (prolog) {
System.out.print("<div class=\"edit unchanged\">");
}
while (aCur < curEdit.getBeginA()) {
System.out.println(rt1.getString(aCur++));
}
if (prolog) {
System.out.print("</div>");
}
if (curEdit.getType() == Edit.Type.INSERT) {
System.out.print("<div class=\"edit added\">");
for (int i = curEdit.getBeginB(); i < curEdit.getEndB(); i++) {
System.out.println(rt2.getString(i));
}
System.out.print("</div>");
}
if (curEdit.getType() == Edit.Type.REPLACE) {
System.out.print("<div class=\"edit changed\"><div class=\"edit removed\">");
for (int i = curEdit.getBeginA(); i < curEdit.getEndA(); i++) {
System.out.println(rt1.getString(i));
}
System.out.print("</div><div class=\"edit added\">");
for (int i = curEdit.getBeginB(); i < curEdit.getEndB(); i++) {
System.out.println(rt2.getString(i));
}
aCur = curEdit.getEndA();
System.out.print("</div></div>");
}
}
boolean prolog = aCur < rt1.size();
if (prolog) {
System.out.print("<div class=\"edit unchanged\">");
}
while (aCur < rt1.size()) {
System.out.println(rt1.getString(aCur++));
}
if (prolog) {
System.out.print("</div>");
}
}
use of org.eclipse.jgit.diff.DiffEntry in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method applyChanges.
/**
* <p>This method takes a range of commits (<code>c1..c2</code>) and performs manual update to ${karaf.home}.
* If ${karaf.home} was also a checked out working copy, it'd be a matter of <code>git pull</code>. We may consider
* this implementation, but now I don't want to keep <code>.git</code> directory in ${karaf.home}. Also, jgit
* doesn't support <code>.git</code> <em>platform agnostic symbolic link</em>
* (see: <code>git init --separate-git-dir</code>)</p>
* <p>We don't have to fetch data from repository blobs, because <code>git</code> still points to checked-out
* working copy</p>
* <p>TODO: maybe we just have to copy <strong>all</strong> files from working copy to ${karaf.home}?</p>
* @param git
* @param commit1
* @param commit2
*/
private void applyChanges(Git git, RevCommit commit1, RevCommit commit2) throws IOException, GitAPIException {
File wcDir = git.getRepository().getWorkTree();
List<DiffEntry> diff = this.gitPatchRepository.diff(git, commit1, commit2);
// Changes to the lib dir get done in the lib.next directory. Lets copy
// the lib dir just in case we do have modification to it.
File lib = new File(karafBase, "lib");
if (lib.isDirectory()) {
FileUtils.copyDirectory(lib, new File(karafBase, "lib.next"));
}
boolean libDirectoryChanged = false;
for (DiffEntry de : diff) {
DiffEntry.ChangeType ct = de.getChangeType();
/*
* old path:
* - file add: always /dev/null
* - file modify: always getNewPath()
* - file delete: always the file being deleted
* - file copy: source file the copy originates from
* - file rename: source file the rename originates from
* new path:
* - file add: always the file being created
* - file modify: always getOldPath()
* - file delete: always /dev/null
* - file copy: destination file the copy ends up at
* - file rename: destination file the rename ends up at
*/
String newPath = de.getNewPath();
String oldPath = de.getOldPath();
switch(ct) {
case ADD:
case MODIFY:
Activator.log(LogService.LOG_DEBUG, "[PATCH-change] Modifying " + newPath);
String targetPath = newPath;
if (newPath.startsWith("lib/")) {
targetPath = "lib.next/" + newPath.substring(4);
libDirectoryChanged = true;
}
File srcFile = new File(wcDir, newPath);
File destFile = new File(karafBase, targetPath);
// we do exception for etc/overrides.properties
if ("etc/overrides.properties".equals(newPath) && srcFile.exists() && srcFile.length() == 0) {
FileUtils.deleteQuietly(destFile);
} else {
FileUtils.copyFile(srcFile, destFile);
}
break;
case DELETE:
Activator.log(LogService.LOG_DEBUG, "[PATCH-change] Deleting " + oldPath);
if (oldPath.startsWith("lib/")) {
oldPath = "lib.next/" + oldPath.substring(4);
libDirectoryChanged = true;
}
FileUtils.deleteQuietly(new File(karafBase, oldPath));
break;
case COPY:
case RENAME:
// not handled now
break;
}
}
if (!libDirectoryChanged) {
// lib.next directory might not be needed.
FileUtils.deleteDirectory(new File(karafBase, "lib.next"));
}
FileUtils.deleteQuietly(new File(karafBase, "patch-info.txt"));
}
use of org.eclipse.jgit.diff.DiffEntry in project fuse-karaf by jboss-fuse.
the class GitPatchManagementServiceImpl method loadPatch.
@Override
public Patch loadPatch(PatchDetailsRequest request) throws PatchException {
File descriptor = new File(patchesDir, request.getPatchId() + ".patch");
try {
Patch patch = loadPatch(descriptor, true);
if (patch == null) {
return null;
}
Git repo = gitPatchRepository.findOrCreateMainGitRepository();
List<DiffEntry> diff = null;
if (request.isFiles() || request.isDiff()) {
// fetch the information from git
ObjectId commitId = repo.getRepository().resolve(patch.getManagedPatch().getCommitId());
RevCommit commit = new RevWalk(repo.getRepository()).parseCommit(commitId);
diff = gitPatchRepository.diff(repo, commit.getParent(0), commit);
}
if (request.isBundles()) {
// it's already in PatchData
}
if (request.isFiles() && diff != null) {
for (DiffEntry de : diff) {
DiffEntry.ChangeType ct = de.getChangeType();
String newPath = de.getNewPath();
String oldPath = de.getOldPath();
switch(ct) {
case ADD:
patch.getManagedPatch().getFilesAdded().add(newPath);
break;
case MODIFY:
patch.getManagedPatch().getFilesModified().add(newPath);
break;
case DELETE:
patch.getManagedPatch().getFilesRemoved().add(oldPath);
break;
default:
break;
}
}
}
if (request.isDiff() && diff != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DiffFormatter formatter = new DiffFormatter(baos);
formatter.setContext(4);
formatter.setRepository(repo.getRepository());
for (DiffEntry de : diff) {
formatter.format(de);
}
formatter.flush();
patch.getManagedPatch().setUnifiedDiff(new String(baos.toByteArray(), "UTF-8"));
}
return patch;
} catch (IOException | GitAPIException e) {
throw new PatchException(e.getMessage(), e);
}
}
Aggregations