private KidWalk buildWalk() { final RepositoryMapping rm = RepositoryMapping.getMapping(resource); if (rm == null) { Activator.logError( NLS.bind(CoreText.GitFileHistory_gitNotAttached, resource.getProject().getName()), null); return null; } final KidWalk w = new KidWalk(rm.getRepository()); gitPath = rm.getRepoRelativePath(resource); w.setTreeFilter( AndTreeFilter.create( PathFilterGroup.createFromStrings(Collections.singleton(gitPath)), TreeFilter.ANY_DIFF)); return w; }
public String convertWorkspacePath(IResource resource) { return mapping.getRepoRelativePath(resource); }
public Object execute(ExecutionEvent event) throws ExecutionException { boolean compareMode = Boolean.TRUE.toString().equals(event.getParameter(HistoryViewCommands.COMPARE_MODE_PARAM)); IStructuredSelection selection = getSelection(getPage()); if (selection.size() < 1) return null; Object input = getPage().getInputInternal().getSingleFile(); if (input == null) return null; IWorkbenchPage workBenchPage = HandlerUtil.getActiveWorkbenchWindowChecked(event).getActivePage(); boolean errorOccurred = false; List<ObjectId> ids = new ArrayList<ObjectId>(); String gitPath = null; if (input instanceof IFile) { IFile resource = (IFile) input; final RepositoryMapping map = RepositoryMapping.getMapping(resource); gitPath = map.getRepoRelativePath(resource); Iterator<?> it = selection.iterator(); while (it.hasNext()) { RevCommit commit = (RevCommit) it.next(); String commitPath = getRenamedPath(gitPath, commit); IFileRevision rev = null; try { rev = CompareUtils.getFileRevision(commitPath, commit, map.getRepository(), null); } catch (IOException e) { Activator.logError( NLS.bind(UIText.GitHistoryPage_errorLookingUpPath, gitPath, commit.getId()), e); errorOccurred = true; } if (rev != null) { if (compareMode) { ITypedElement right = CompareUtils.getFileRevisionTypedElement(commitPath, commit, map.getRepository()); final GitCompareFileRevisionEditorInput in = new GitCompareFileRevisionEditorInput( SaveableCompareEditorInput.createFileElement(resource), right, null); try { CompareUtils.openInCompare(workBenchPage, in); } catch (Exception e) { errorOccurred = true; } } else try { EgitUiEditorUtils.openEditor( getPart(event).getSite().getPage(), rev, new NullProgressMonitor()); } catch (CoreException e) { Activator.logError(UIText.GitHistoryPage_openFailed, e); errorOccurred = true; } } else ids.add(commit.getId()); } } if (input instanceof File) { File fileInput = (File) input; Repository repo = getRepository(event); gitPath = getRepoRelativePath(repo, fileInput); Iterator<?> it = selection.iterator(); while (it.hasNext()) { RevCommit commit = (RevCommit) it.next(); String commitPath = getRenamedPath(gitPath, commit); IFileRevision rev = null; try { rev = CompareUtils.getFileRevision(commitPath, commit, repo, null); } catch (IOException e) { Activator.logError( NLS.bind(UIText.GitHistoryPage_errorLookingUpPath, commitPath, commit.getId()), e); errorOccurred = true; } if (rev != null) { if (compareMode) try { ITypedElement left = CompareUtils.getFileRevisionTypedElement( gitPath, new RevWalk(repo).parseCommit(repo.resolve(Constants.HEAD)), repo); ITypedElement right = CompareUtils.getFileRevisionTypedElement(commitPath, commit, repo); final GitCompareFileRevisionEditorInput in = new GitCompareFileRevisionEditorInput(left, right, null); CompareUtils.openInCompare(workBenchPage, in); } catch (IOException e) { errorOccurred = true; } else try { EgitUiEditorUtils.openEditor( getPart(event).getSite().getPage(), rev, new NullProgressMonitor()); } catch (CoreException e) { Activator.logError(UIText.GitHistoryPage_openFailed, e); errorOccurred = true; } } else ids.add(commit.getId()); } } if (errorOccurred) Activator.showError(UIText.GitHistoryPage_openFailed, null); if (ids.size() > 0) { StringBuilder idList = new StringBuilder(""); // $NON-NLS-1$ for (ObjectId objectId : ids) idList.append(objectId.getName()).append(' '); MessageDialog.openError( getPart(event).getSite().getShell(), UIText.GitHistoryPage_fileNotFound, NLS.bind(UIText.GitHistoryPage_notContainedInCommits, gitPath, idList.toString())); } return null; }
/** * Process the EGit history associated with a given project. * * @param selectedProject selected project, presumably an object contribution selection * @throws CoreException * @throws IOException */ public void processHistory(IProject selectedProject, IProgressMonitor monitor) throws CoreException, IOException { // find the repository mapping for the project // if none found, return RepositoryMapping repositoryMapping = RepositoryMapping.getMapping((IResource) selectedProject); if (repositoryMapping == null) { CertWareLog.logWarning( String.format("%s %s", "Missing repository for project", selectedProject.getName())); return; } // build the commit history model, load it from the tree walk final CommitHistory commitHistory = ScoFactory.eINSTANCE.createCommitHistory(); Repository repo = repositoryMapping.getRepository(); RevWalk revWalk = new RevWalk(repo); ObjectId headObject = repo.resolve("HEAD"); revWalk.markStart(revWalk.parseCommit(headObject)); final Set<String> repositoryPaths = Collections.singleton(repositoryMapping.getRepoRelativePath(selectedProject)); revWalk.setTreeFilter(PathFilterGroup.createFromStrings(repositoryPaths)); for (RevCommit commit : revWalk) { String commitName = commit.getName(); ArtifactCommit artifactCommit = ScoFactory.eINSTANCE.createArtifactCommit(); artifactCommit.setCommitIdentifier(commitName); commitHistory.getCommitRecord().add(artifactCommit); } revWalk.dispose(); // use the Git provider to find the file history, then converge into the model GitProvider provider = (GitProvider) RepositoryProvider.getProvider(selectedProject); IFileHistoryProvider fileHistoryProvider = provider.getFileHistoryProvider(); IResource[] projectMembers = selectedProject.members(); monitor.beginTask("Processing project resources", projectMembers.length); for (IResource resource : projectMembers) { processResource(resource, fileHistoryProvider, commitHistory, monitor); monitor.worked(1); if (monitor.isCanceled()) { return; } } // model complete with commit history and associated file sizes // write the resulting model to an SCO file // expecting preference to have no extension, so add it if necessary IPreferenceStore store = Activator.getDefault().getPreferenceStore(); String fileName = store.getString(PreferenceConstants.P_FILENAME_SCO); if (fileName.endsWith(ICertWareConstants.SCO_EXTENSION) == false) { fileName = fileName + '.' + ICertWareConstants.SCO_EXTENSION; } // fully specify the path to the new file given the container project final String modelFile = selectedProject.getFullPath().toPortableString() + IPath.SEPARATOR + fileName; // create the resource in a workspace modify operation WorkspaceModifyOperation operation = new WorkspaceModifyOperation() { @Override protected void execute(IProgressMonitor progressMonitor) { try { // create a resource set and resource for a new file ResourceSet resourceSet = new ResourceSetImpl(); URI fileURI = URI.createPlatformResourceURI(modelFile, true); Resource resource = resourceSet.createResource(fileURI); resource.getContents().add(commitHistory); // save the contents of the resource to the file system Map<Object, Object> options = new HashMap<Object, Object>(); options.put(XMLResource.OPTION_ENCODING, FILE_ENCODING); resource.save(options); } catch (Exception e) { CertWareLog.logError(String.format("%s %s", "Saving SCO file", modelFile), e); } } }; // modify the workspace try { operation.run(monitor); } catch (Exception e) { CertWareLog.logError( String.format("%s %s", "Modifying workspace for", selectedProject.getName()), e); } monitor.done(); }
private void buildMaps( Repository repository, RevCommit baseCommit, RevCommit compareCommit, IProgressMonitor monitor) throws InterruptedException, IOException { monitor.beginTask(UIText.CompareTreeView_AnalyzingRepositoryTaskText, IProgressMonitor.UNKNOWN); boolean useIndex = compareVersion.equals(INDEX_VERSION); deletedPaths.clear(); equalContentPaths.clear(); baseVersionMap.clear(); compareVersionMap.clear(); compareVersionPathsWithChildren.clear(); addedPaths.clear(); baseVersionPathsWithChildren.clear(); boolean checkIgnored = false; TreeWalk tw = new TreeWalk(repository); try { int baseTreeIndex; if (baseCommit == null) { checkIgnored = true; baseTreeIndex = tw.addTree( new AdaptableFileTreeIterator( repository, ResourcesPlugin.getWorkspace().getRoot())); } else baseTreeIndex = tw.addTree( new CanonicalTreeParser(null, repository.newObjectReader(), baseCommit.getTree())); int compareTreeIndex; if (!useIndex) compareTreeIndex = tw.addTree( new CanonicalTreeParser( null, repository.newObjectReader(), compareCommit.getTree())); else compareTreeIndex = tw.addTree(new DirCacheIterator(repository.readDirCache())); if (input instanceof IResource[]) { IResource[] resources = (IResource[]) input; List<TreeFilter> orFilters = new ArrayList<TreeFilter>(resources.length); for (IResource resource : resources) { String relPath = repositoryMapping.getRepoRelativePath(resource); if (relPath.length() > 0) orFilters.add(PathFilter.create(relPath)); } if (orFilters.size() > 1) tw.setFilter(OrTreeFilter.create(orFilters)); else if (orFilters.size() == 1) tw.setFilter(orFilters.get(0)); } tw.setRecursive(true); if (monitor.isCanceled()) throw new InterruptedException(); while (tw.next()) { if (monitor.isCanceled()) throw new InterruptedException(); AbstractTreeIterator compareVersionIterator = tw.getTree(compareTreeIndex, AbstractTreeIterator.class); AbstractTreeIterator baseVersionIterator = tw.getTree(baseTreeIndex, AbstractTreeIterator.class); if (checkIgnored && baseVersionIterator != null && ((WorkingTreeIterator) baseVersionIterator).isEntryIgnored()) continue; if (compareVersionIterator != null && baseVersionIterator != null) { monitor.setTaskName(baseVersionIterator.getEntryPathString()); IPath currentPath = new Path(baseVersionIterator.getEntryPathString()); if (!useIndex) compareVersionMap.put( currentPath, GitFileRevision.inCommit( repository, compareCommit, baseVersionIterator.getEntryPathString(), tw.getObjectId(compareTreeIndex))); else compareVersionMap.put( currentPath, GitFileRevision.inIndex(repository, baseVersionIterator.getEntryPathString())); if (baseCommit != null) baseVersionMap.put( currentPath, GitFileRevision.inCommit( repository, baseCommit, baseVersionIterator.getEntryPathString(), tw.getObjectId(baseTreeIndex))); boolean equalContent = compareVersionIterator .getEntryObjectId() .equals(baseVersionIterator.getEntryObjectId()); if (equalContent) equalContentPaths.add(currentPath); if (equalContent && !showEquals) continue; while (currentPath.segmentCount() > 0) { currentPath = currentPath.removeLastSegments(1); if (!baseVersionPathsWithChildren.add(currentPath)) break; } } else if (baseVersionIterator != null && compareVersionIterator == null) { monitor.setTaskName(baseVersionIterator.getEntryPathString()); // only on base side IPath currentPath = new Path(baseVersionIterator.getEntryPathString()); addedPaths.add(currentPath); if (baseCommit != null) baseVersionMap.put( currentPath, GitFileRevision.inCommit( repository, baseCommit, baseVersionIterator.getEntryPathString(), tw.getObjectId(baseTreeIndex))); while (currentPath.segmentCount() > 0) { currentPath = currentPath.removeLastSegments(1); if (!baseVersionPathsWithChildren.add(currentPath)) break; } } else if (compareVersionIterator != null && baseVersionIterator == null) { monitor.setTaskName(compareVersionIterator.getEntryPathString()); // only on compare side IPath currentPath = new Path(compareVersionIterator.getEntryPathString()); deletedPaths.add(currentPath); List<PathNodeAdapter> children = compareVersionPathsWithChildren.get(currentPath.removeLastSegments(1)); if (children == null) { children = new ArrayList<PathNodeAdapter>(1); compareVersionPathsWithChildren.put(currentPath.removeLastSegments(1), children); } children.add(new PathNodeAdapter(new PathNode(currentPath, Type.FILE_DELETED))); if (!useIndex) compareVersionMap.put( currentPath, GitFileRevision.inCommit( repository, compareCommit, compareVersionIterator.getEntryPathString(), tw.getObjectId(compareTreeIndex))); else compareVersionMap.put( currentPath, GitFileRevision.inIndex(repository, compareVersionIterator.getEntryPathString())); } } } finally { tw.release(); monitor.done(); } }
private void reactOnOpen(OpenEvent event) { Object selected = ((IStructuredSelection) event.getSelection()).getFirstElement(); ITypedElement left; ITypedElement right; if (selected instanceof IContainer) { // open/close folder TreeViewer tv = (TreeViewer) event.getViewer(); tv.setExpandedState(selected, !tv.getExpandedState(selected)); return; } else if (selected instanceof IFile) { final IFile res = (IFile) selected; left = new EditableRevision(new LocalFileRevision(res)) { @Override public void setContent(final byte[] newContent) { try { PlatformUI.getWorkbench() .getProgressService() .run( false, false, new IRunnableWithProgress() { public void run(IProgressMonitor myMonitor) throws InvocationTargetException, InterruptedException { try { res.setContents( new ByteArrayInputStream(newContent), false, true, myMonitor); } catch (CoreException e) { throw new InvocationTargetException(e); } } }); } catch (InvocationTargetException e) { Activator.handleError( e.getTargetException().getMessage(), e.getTargetException(), true); } catch (InterruptedException e) { // ignore here } } }; GitFileRevision rightRevision = compareVersionMap.get(new Path(repositoryMapping.getRepoRelativePath(res))); if (rightRevision == null) { right = new GitCompareFileRevisionEditorInput.EmptyTypedElement( NLS.bind( UIText.CompareTreeView_ItemNotFoundInVersionMessage, res.getName(), getCompareVersion())); } else { String encoding = CompareCoreUtils.getResourceEncoding(res); right = new FileRevisionTypedElement(rightRevision, encoding); } GitCompareFileRevisionEditorInput compareInput = new GitCompareFileRevisionEditorInput( left, right, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()); CompareUtils.openInCompare( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), compareInput); } else if (selected instanceof GitFileRevision) { GitFileRevision rightRevision = (GitFileRevision) selected; left = new GitCompareFileRevisionEditorInput.EmptyTypedElement( NLS.bind( UIText.CompareTreeView_ItemNotFoundInVersionMessage, rightRevision.getName(), getBaseVersion())); right = new FileRevisionTypedElement(rightRevision); } else if (selected instanceof PathNode) { PathNode node = (PathNode) selected; switch (node.type) { case FILE_BOTH_SIDES_DIFFER: // fall through case FILE_BOTH_SIDES_SAME: { // open a compare editor with both sides filled GitFileRevision rightRevision = compareVersionMap.get(node.path); right = new FileRevisionTypedElement(rightRevision); GitFileRevision leftRevision = baseVersionMap.get(node.path); left = new FileRevisionTypedElement(leftRevision); break; } case FILE_DELETED: { // open compare editor with left side empty GitFileRevision rightRevision = compareVersionMap.get(node.path); right = new FileRevisionTypedElement(rightRevision); left = new GitCompareFileRevisionEditorInput.EmptyTypedElement( NLS.bind( UIText.CompareTreeView_ItemNotFoundInVersionMessage, rightRevision.getName(), getBaseVersion())); break; } case FILE_ADDED: { // open compare editor with right side empty GitFileRevision leftRevision = baseVersionMap.get(node.path); left = new FileRevisionTypedElement(leftRevision); right = new GitCompareFileRevisionEditorInput.EmptyTypedElement( NLS.bind( UIText.CompareTreeView_ItemNotFoundInVersionMessage, leftRevision.getName(), getCompareVersion())); break; } case FOLDER: // open/close folder TreeViewer tv = (TreeViewer) event.getViewer(); tv.setExpandedState(selected, !tv.getExpandedState(selected)); return; default: return; } } else if (selected instanceof PathNodeAdapter) { // deleted in workspace PathNodeAdapter node = (PathNodeAdapter) selected; GitFileRevision rightRevision = compareVersionMap.get(node.pathNode.path); right = new FileRevisionTypedElement(rightRevision); left = new GitCompareFileRevisionEditorInput.EmptyTypedElement( NLS.bind( UIText.CompareTreeView_ItemNotFoundInVersionMessage, node.pathNode.path.lastSegment(), getBaseVersion())); } else return; GitCompareFileRevisionEditorInput compareInput = new GitCompareFileRevisionEditorInput( left, right, PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()); CompareUtils.openInCompare( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), compareInput); }
@Override protected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { // make sure all resources belong to the same repository try (RevWalk rw = new RevWalk(repository)) { monitor.beginTask( UIText.GitCompareEditorInput_CompareResourcesTaskName, IProgressMonitor.UNKNOWN); for (IResource resource : resources) { RepositoryMapping map = RepositoryMapping.getMapping(resource.getProject()); if (map == null) { throw new InvocationTargetException( new IllegalStateException( UIText.GitCompareEditorInput_ResourcesInDifferentReposMessagge)); } if (repository != null && repository != map.getRepository()) throw new InvocationTargetException( new IllegalStateException( UIText.GitCompareEditorInput_ResourcesInDifferentReposMessagge)); String repoRelativePath = map.getRepoRelativePath(resource); filterPathStrings.add(repoRelativePath); DiffNode node = new DiffNode(Differencer.NO_CHANGE) { @Override public Image getImage() { return FOLDER_IMAGE; } }; diffRoots.put(new Path(map.getRepoRelativePath(resource)), node); repository = map.getRepository(); } if (repository == null) throw new InvocationTargetException( new IllegalStateException( UIText.GitCompareEditorInput_ResourcesInDifferentReposMessagge)); if (monitor.isCanceled()) throw new InterruptedException(); final RevCommit baseCommit; try { try { baseCommit = rw.parseCommit(repository.resolve(baseVersion)); } catch (IOException e) { throw new InvocationTargetException(e); } final RevCommit compareCommit; if (compareVersion == null) { compareCommit = null; } else { try { compareCommit = rw.parseCommit(repository.resolve(compareVersion)); } catch (IOException e) { throw new InvocationTargetException(e); } } if (monitor.isCanceled()) throw new InterruptedException(); // set the labels CompareConfiguration config = getCompareConfiguration(); config.setLeftLabel(compareVersion); config.setRightLabel(baseVersion); // set title and icon if (resources.length == 0) { Object[] titleParameters = new Object[] { Activator.getDefault().getRepositoryUtil().getRepositoryName(repository), CompareUtils.truncatedRevision(compareVersion), CompareUtils.truncatedRevision(baseVersion) }; setTitle(NLS.bind(UIText.GitCompareEditorInput_EditorTitle, titleParameters)); } else if (resources.length == 1) { Object[] titleParameters = new Object[] { resources[0].getFullPath().makeRelative().toString(), CompareUtils.truncatedRevision(compareVersion), CompareUtils.truncatedRevision(baseVersion) }; setTitle( NLS.bind(UIText.GitCompareEditorInput_EditorTitleSingleResource, titleParameters)); } else { setTitle( NLS.bind( UIText.GitCompareEditorInput_EditorTitleMultipleResources, CompareUtils.truncatedRevision(compareVersion), CompareUtils.truncatedRevision(baseVersion))); } // build the nodes try { return buildDiffContainer(baseCommit, compareCommit, monitor); } catch (IOException e) { throw new InvocationTargetException(e); } } finally { monitor.done(); } } }