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;
}
}
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;
}
}
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;
}
Aggregations