Search in sources :

Example 16 with DiffEntry

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());
        }
    }
}
Also used : AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) DiffConfig(org.eclipse.jgit.diff.DiffConfig) CanonicalTreeParser(org.eclipse.jgit.treewalk.CanonicalTreeParser) Repository(org.eclipse.jgit.lib.Repository) RenameDetector(org.eclipse.jgit.diff.RenameDetector) RepositoryMapping(org.eclipse.egit.core.project.RepositoryMapping) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ObjectLoader(org.eclipse.jgit.lib.ObjectLoader) DirCacheIterator(org.eclipse.jgit.dircache.DirCacheIterator) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) RevTree(org.eclipse.jgit.revwalk.RevTree) RevCommit(org.eclipse.jgit.revwalk.RevCommit) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Example 17 with DiffEntry

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);
}
Also used : Composite(org.eclipse.swt.widgets.Composite) ScrolledComposite(org.eclipse.swt.custom.ScrolledComposite) SelectionAdapter(org.eclipse.swt.events.SelectionAdapter) Label(org.eclipse.swt.widgets.Label) DiffViewer(org.eclipse.egit.ui.internal.commit.DiffViewer) DiffRegionFormatter(org.eclipse.egit.ui.internal.commit.DiffRegionFormatter) SelectionEvent(org.eclipse.swt.events.SelectionEvent) ObjectReader(org.eclipse.jgit.lib.ObjectReader) FileDiff(org.eclipse.egit.ui.internal.history.FileDiff) EditList(org.eclipse.jgit.diff.EditList) DiffDocument(org.eclipse.egit.ui.internal.commit.DiffDocument) Link(org.eclipse.swt.widgets.Link) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Example 18 with DiffEntry

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>");
    }
}
Also used : Edit(org.eclipse.jgit.diff.Edit) ByteArrayOutputStream(java.io.ByteArrayOutputStream) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RawText(org.eclipse.jgit.diff.RawText) CanonicalTreeParser(org.eclipse.jgit.treewalk.CanonicalTreeParser) AbbreviatedObjectId(org.eclipse.jgit.lib.AbbreviatedObjectId) ObjectReader(org.eclipse.jgit.lib.ObjectReader) EditList(org.eclipse.jgit.diff.EditList) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) DiffEntry(org.eclipse.jgit.diff.DiffEntry) Test(org.junit.Test)

Example 19 with DiffEntry

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"));
}
Also used : ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Example 20 with DiffEntry

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);
    }
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Git(org.eclipse.jgit.api.Git) PatchException(org.jboss.fuse.patch.management.PatchException) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) File(java.io.File) Patch(org.jboss.fuse.patch.management.Patch) ManagedPatch(org.jboss.fuse.patch.management.ManagedPatch) DiffEntry(org.eclipse.jgit.diff.DiffEntry) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

DiffEntry (org.eclipse.jgit.diff.DiffEntry)66 RevCommit (org.eclipse.jgit.revwalk.RevCommit)24 RevWalk (org.eclipse.jgit.revwalk.RevWalk)23 DiffFormatter (org.eclipse.jgit.diff.DiffFormatter)22 ObjectReader (org.eclipse.jgit.lib.ObjectReader)21 CanonicalTreeParser (org.eclipse.jgit.treewalk.CanonicalTreeParser)20 IOException (java.io.IOException)19 Git (org.eclipse.jgit.api.Git)18 ObjectId (org.eclipse.jgit.lib.ObjectId)15 ArrayList (java.util.ArrayList)14 File (java.io.File)13 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)12 RevTree (org.eclipse.jgit.revwalk.RevTree)11 ByteArrayOutputStream (java.io.ByteArrayOutputStream)8 Path (java.nio.file.Path)8 Test (org.junit.Test)8 FileTreeIterator (org.eclipse.jgit.treewalk.FileTreeIterator)7 TreeWalk (org.eclipse.jgit.treewalk.TreeWalk)7 Ref (org.eclipse.jgit.lib.Ref)6 Repository (org.eclipse.jgit.lib.Repository)6