Search in sources :

Example 1 with EmptyTypedElement

use of org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement in project egit by eclipse.

the class GitMergeEditorInput method buildDiffContainer.

private IDiffContainer buildDiffContainer(Repository repository, RevCommit headCommit, RevCommit ancestorCommit, List<String> filterPaths, RevWalk rw, IProgressMonitor monitor) throws IOException, InterruptedException {
    monitor.setTaskName(UIText.GitMergeEditorInput_CalculatingDiffTaskName);
    IDiffContainer result = new DiffNode(Differencer.CONFLICTING);
    try (TreeWalk tw = new TreeWalk(repository)) {
        int dirCacheIndex = tw.addTree(new DirCacheIterator(repository.readDirCache()));
        int fileTreeIndex = tw.addTree(new FileTreeIterator(repository));
        int repositoryTreeIndex = tw.addTree(rw.parseTree(repository.resolve(Constants.HEAD)));
        // skip ignored resources
        NotIgnoredFilter notIgnoredFilter = new NotIgnoredFilter(fileTreeIndex);
        // filter by selected resources
        if (filterPaths.size() > 1) {
            List<TreeFilter> suffixFilters = new ArrayList<>();
            for (String filterPath : filterPaths) suffixFilters.add(PathFilter.create(filterPath));
            TreeFilter otf = OrTreeFilter.create(suffixFilters);
            tw.setFilter(AndTreeFilter.create(otf, notIgnoredFilter));
        } else if (filterPaths.size() > 0) {
            String path = filterPaths.get(0);
            if (path.length() == 0)
                tw.setFilter(notIgnoredFilter);
            else
                tw.setFilter(AndTreeFilter.create(PathFilter.create(path), notIgnoredFilter));
        } else
            tw.setFilter(notIgnoredFilter);
        tw.setRecursive(true);
        while (tw.next()) {
            if (monitor.isCanceled())
                throw new InterruptedException();
            String gitPath = tw.getPathString();
            monitor.setTaskName(gitPath);
            FileTreeIterator fit = tw.getTree(fileTreeIndex, FileTreeIterator.class);
            if (fit == null)
                continue;
            DirCacheIterator dit = tw.getTree(dirCacheIndex, DirCacheIterator.class);
            final DirCacheEntry dirCacheEntry = dit == null ? null : dit.getDirCacheEntry();
            boolean conflicting = dirCacheEntry != null && dirCacheEntry.getStage() > 0;
            AbstractTreeIterator rt = tw.getTree(repositoryTreeIndex, AbstractTreeIterator.class);
            // compare local file against HEAD to see if it was modified
            boolean modified = rt != null && !fit.getEntryObjectId().equals(rt.getEntryObjectId());
            // if this is neither conflicting nor changed, we skip it
            if (!conflicting && !modified)
                continue;
            ITypedElement right;
            if (conflicting) {
                GitFileRevision revision = GitFileRevision.inIndex(repository, gitPath, DirCacheEntry.STAGE_3);
                String encoding = CompareCoreUtils.getResourceEncoding(repository, gitPath);
                right = new FileRevisionTypedElement(revision, encoding);
            } else
                right = CompareUtils.getFileRevisionTypedElement(gitPath, headCommit, repository);
            // can this really happen?
            if (right instanceof EmptyTypedElement)
                continue;
            IFileRevision rev;
            // if the file is not conflicting (as it was auto-merged)
            // we will show the auto-merged (local) version
            Path repositoryPath = new Path(repository.getWorkTree().getAbsolutePath());
            IPath location = repositoryPath.append(fit.getEntryPathString());
            IFile file = ResourceUtil.getFileForLocation(location, false);
            if (!conflicting || useWorkspace) {
                if (file != null)
                    rev = new LocalFileRevision(file);
                else
                    rev = new WorkingTreeFileRevision(location.toFile());
            } else {
                rev = GitFileRevision.inIndex(repository, gitPath, DirCacheEntry.STAGE_2);
            }
            IRunnableContext runnableContext = getContainer();
            if (runnableContext == null)
                runnableContext = PlatformUI.getWorkbench().getProgressService();
            EditableRevision leftEditable;
            if (file != null)
                leftEditable = new ResourceEditableRevision(rev, file, runnableContext);
            else
                leftEditable = new LocationEditableRevision(rev, location, runnableContext);
            // make sure we don't need a round trip later
            try {
                leftEditable.cacheContents(monitor);
            } catch (CoreException e) {
                throw new IOException(e.getMessage());
            }
            int kind = Differencer.NO_CHANGE;
            if (conflicting)
                kind = Differencer.CONFLICTING;
            else if (modified)
                kind = Differencer.PSEUDO_CONFLICT;
            IDiffContainer fileParent = getFileParent(result, repositoryPath, file, location);
            ITypedElement anc;
            if (ancestorCommit != null)
                anc = CompareUtils.getFileRevisionTypedElement(gitPath, ancestorCommit, repository);
            else
                anc = null;
            // instead of null
            if (anc instanceof EmptyTypedElement)
                anc = null;
            // create the node as child
            new DiffNode(fileParent, kind, anc, leftEditable, right);
        }
        return result;
    }
}
Also used : IRunnableContext(org.eclipse.jface.operation.IRunnableContext) NotIgnoredFilter(org.eclipse.jgit.treewalk.filter.NotIgnoredFilter) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) IFile(org.eclipse.core.resources.IFile) DiffNode(org.eclipse.compare.structuremergeviewer.DiffNode) ArrayList(java.util.ArrayList) LocationEditableRevision(org.eclipse.egit.ui.internal.revision.LocationEditableRevision) IDiffContainer(org.eclipse.compare.structuremergeviewer.IDiffContainer) ResourceEditableRevision(org.eclipse.egit.ui.internal.revision.ResourceEditableRevision) GitFileRevision(org.eclipse.egit.core.internal.storage.GitFileRevision) WorkingTreeFileRevision(org.eclipse.egit.core.internal.storage.WorkingTreeFileRevision) EmptyTypedElement(org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement) DirCacheIterator(org.eclipse.jgit.dircache.DirCacheIterator) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) IPath(org.eclipse.core.runtime.IPath) Path(org.eclipse.core.runtime.Path) LocalFileRevision(org.eclipse.egit.ui.internal.revision.LocalFileRevision) IPath(org.eclipse.core.runtime.IPath) IFileRevision(org.eclipse.team.core.history.IFileRevision) ITypedElement(org.eclipse.compare.ITypedElement) IOException(java.io.IOException) AbstractTreeIterator(org.eclipse.jgit.treewalk.AbstractTreeIterator) CoreException(org.eclipse.core.runtime.CoreException) TreeFilter(org.eclipse.jgit.treewalk.filter.TreeFilter) AndTreeFilter(org.eclipse.jgit.treewalk.filter.AndTreeFilter) OrTreeFilter(org.eclipse.jgit.treewalk.filter.OrTreeFilter) FileRevisionTypedElement(org.eclipse.egit.ui.internal.revision.FileRevisionTypedElement) LocationEditableRevision(org.eclipse.egit.ui.internal.revision.LocationEditableRevision) ResourceEditableRevision(org.eclipse.egit.ui.internal.revision.ResourceEditableRevision) EditableRevision(org.eclipse.egit.ui.internal.revision.EditableRevision) FileTreeIterator(org.eclipse.jgit.treewalk.FileTreeIterator)

Example 2 with EmptyTypedElement

use of org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement in project egit by eclipse.

the class CompareUtils method getHeadTypedElement.

/**
 * Get a typed element for the file as contained in HEAD. Tries to return
 * the last commit that modified the file in order to have more useful
 * author information.
 * <p>
 * Returns an empty typed element if there is not yet a head (initial import
 * case).
 * <p>
 * If there is an error getting the HEAD commit, it is handled and null
 * returned.
 *
 * @param repository
 * @param repoRelativePath
 * @return typed element, or null if there was an error getting the HEAD
 *         commit
 */
public static ITypedElement getHeadTypedElement(Repository repository, String repoRelativePath) {
    try {
        Ref head = repository.exactRef(Constants.HEAD);
        if (head == null || head.getObjectId() == null)
            // Initial import, not yet a HEAD commit
            return // $NON-NLS-1$
            new EmptyTypedElement("");
        RevCommit latestFileCommit;
        try (RevWalk rw = new RevWalk(repository)) {
            RevCommit headCommit = rw.parseCommit(head.getObjectId());
            rw.markStart(headCommit);
            rw.setTreeFilter(AndTreeFilter.create(PathFilterGroup.createFromStrings(repoRelativePath), TreeFilter.ANY_DIFF));
            rw.setRewriteParents(false);
            latestFileCommit = rw.next();
            // Fall back to HEAD
            if (latestFileCommit == null)
                latestFileCommit = headCommit;
        }
        return CompareUtils.getFileRevisionTypedElement(repoRelativePath, latestFileCommit, repository);
    } catch (IOException e) {
        Activator.handleError(UIText.CompareUtils_errorGettingHeadCommit, e, true);
        return null;
    }
}
Also used : Ref(org.eclipse.jgit.lib.Ref) EmptyTypedElement(org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 3 with EmptyTypedElement

use of org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement in project egit by eclipse.

the class CompareUtils method getFileRevisionTypedElementForCommonAncestor.

/**
 * Creates a {@link ITypedElement} for the commit which is the common
 * ancestor of the provided commits. Returns null if no such commit exists
 * or if {@code gitPath} is not contained in the common ancestor or if the
 * common ancestor is equal to one of the given commits
 *
 * @param gitPath
 *            path within the ancestor commit's tree of the file.
 * @param commit1
 * @param commit2
 * @param db
 *            the repository this commit was loaded out of.
 * @return an instance of {@link ITypedElement} which can be used in
 *         {@link CompareEditorInput}
 */
public static ITypedElement getFileRevisionTypedElementForCommonAncestor(final String gitPath, ObjectId commit1, ObjectId commit2, Repository db) {
    ITypedElement ancestor = null;
    RevCommit commonAncestor = null;
    try {
        commonAncestor = RevUtils.getCommonAncestor(db, commit1, commit2);
    } catch (IOException e) {
        Activator.logError(NLS.bind(UIText.CompareUtils_errorCommonAncestor, commit1.getName(), commit2.getName()), e);
    }
    if (commonAncestor != null) {
        if (commit1.equals(commonAncestor.getId()) || commit2.equals(commonAncestor.getId())) {
            // of given commits, see bug 512395
            return null;
        }
        ITypedElement ancestorCandidate = CompareUtils.getFileRevisionTypedElement(gitPath, commonAncestor, db);
        if (!(ancestorCandidate instanceof EmptyTypedElement))
            ancestor = ancestorCandidate;
    }
    return ancestor;
}
Also used : ITypedElement(org.eclipse.compare.ITypedElement) EmptyTypedElement(org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement) IOException(java.io.IOException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

IOException (java.io.IOException)3 EmptyTypedElement (org.eclipse.egit.ui.internal.revision.GitCompareFileRevisionEditorInput.EmptyTypedElement)3 ITypedElement (org.eclipse.compare.ITypedElement)2 RevCommit (org.eclipse.jgit.revwalk.RevCommit)2 ArrayList (java.util.ArrayList)1 DiffNode (org.eclipse.compare.structuremergeviewer.DiffNode)1 IDiffContainer (org.eclipse.compare.structuremergeviewer.IDiffContainer)1 IFile (org.eclipse.core.resources.IFile)1 CoreException (org.eclipse.core.runtime.CoreException)1 IPath (org.eclipse.core.runtime.IPath)1 Path (org.eclipse.core.runtime.Path)1 GitFileRevision (org.eclipse.egit.core.internal.storage.GitFileRevision)1 WorkingTreeFileRevision (org.eclipse.egit.core.internal.storage.WorkingTreeFileRevision)1 EditableRevision (org.eclipse.egit.ui.internal.revision.EditableRevision)1 FileRevisionTypedElement (org.eclipse.egit.ui.internal.revision.FileRevisionTypedElement)1 LocalFileRevision (org.eclipse.egit.ui.internal.revision.LocalFileRevision)1 LocationEditableRevision (org.eclipse.egit.ui.internal.revision.LocationEditableRevision)1 ResourceEditableRevision (org.eclipse.egit.ui.internal.revision.ResourceEditableRevision)1 IRunnableContext (org.eclipse.jface.operation.IRunnableContext)1 DirCacheEntry (org.eclipse.jgit.dircache.DirCacheEntry)1