From 674fca20198a4f6acfc046c1388fd3b3e190e464 Mon Sep 17 00:00:00 2001 From: Dave Watson Date: Fri, 15 Jun 2007 21:47:21 -0400 Subject: [PATCH] Commit dialog now shows information much more similar to git-commit. Added IndexDiff class to compare GitIndex with a tree. CommitDialog uses IndexDiff, as well as checking what's in the filesystem with what's in the index. Does not yet show things that aren't in the index at all, but merely modified in the filesystem. Signed-off-by: David Watson --- .../egit/ui/internal/actions/CommitAction.java | 67 ++++++++++++++-- .../egit/ui/internal/dialogs/CommitDialog.java | 11 ++- .../src/org/spearce/jgit/lib/IndexDiff.java | 90 ++++++++++++++++++++++ .../tst/org/spearce/jgit/lib/IndexDiffTest.java | 71 +++++++++++++++++ 4 files changed, 231 insertions(+), 8 deletions(-) create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/IndexDiff.java create mode 100644 org.spearce.jgit/tst/org/spearce/jgit/lib/IndexDiffTest.java diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java index ecfe4d2b..790b51c0 100644 --- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -29,6 +30,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; @@ -39,6 +41,10 @@ import org.eclipse.ui.IWorkbenchPart; import org.spearce.egit.core.project.GitProjectData; import org.spearce.egit.core.project.RepositoryMapping; import org.spearce.egit.ui.internal.dialogs.CommitDialog; +import org.spearce.jgit.lib.GitIndex; +import org.spearce.jgit.lib.IndexDiff; +import org.spearce.jgit.lib.Repository; +import org.spearce.jgit.lib.Tree; public class CommitAction implements IObjectActionDelegate { private IWorkbenchPart wp; @@ -49,10 +55,15 @@ public class CommitAction implements IObjectActionDelegate { } public void run(IAction act) { + files.clear(); try { - buildList(); + buildIndexHeadDiffList(); + if (false) + buildList(); } catch (CoreException e) { return; + } catch (IOException e) { + return; } if (files.isEmpty()) { MessageDialog.openWarning(wp.getSite().getShell(), @@ -73,6 +84,52 @@ public class CommitAction implements IObjectActionDelegate { } } + private void buildIndexHeadDiffList() throws IOException { + for (IProject project : listProjects()) { + final GitProjectData projectData = GitProjectData.get(project); + if (projectData != null) { + RepositoryMapping repositoryMapping = projectData.getRepositoryMapping(project); + Repository repository = repositoryMapping.getRepository(); + Tree head = repository.mapTree("HEAD"); + GitIndex index = repository.getIndex(); + IndexDiff indexDiff = new IndexDiff(head, index); + indexDiff.diff(); + + includeList(project, indexDiff.getAdded()); + includeList(project, indexDiff.getChanged()); + includeList(project, indexDiff.getRemoved()); + } + } + } + + private void includeList(IProject project, HashSet added) { + for (String filename : added) { + Path path = new Path(filename); + try { + IResource member = project.getWorkspace().getRoot().getFile(path); + if (member == null) + member = project.getFile(path); + + if (member != null && member instanceof IFile) { + files.add((IFile) member); + } else { + System.out.println("Couldn't find " + filename); + } + } catch (Exception t) { continue;} // if it's outside the workspace, bad things happen + } + } + + private ArrayList listProjects() { + ArrayList projects = new ArrayList(); + + for (Iterator i = rsrcList.iterator(); i.hasNext();) { + IResource res = (IResource) i.next(); + if (!projects.contains(res.getProject())) + projects.add(res.getProject()); + } + return projects; + } + private ArrayList files = new ArrayList(); private void buildList() throws CoreException { @@ -91,10 +148,10 @@ public class CommitAction implements IObjectActionDelegate { tryAddResource((IFile) resource, projectData); } else { resource.accept(new IResourceVisitor() { - public boolean visit(IResource resource) + public boolean visit(IResource rsrc) throws CoreException { - if (resource instanceof IFile) { - tryAddResource((IFile) resource, projectData); + if (rsrc instanceof IFile) { + tryAddResource((IFile) rsrc, projectData); return false; } return true; @@ -105,7 +162,7 @@ public class CommitAction implements IObjectActionDelegate { } } - private void tryAddResource(IFile resource, GitProjectData projectData) { + public void tryAddResource(IFile resource, GitProjectData projectData) { if (files.contains(resource)) return; diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/dialogs/CommitDialog.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/dialogs/CommitDialog.java index d43ce02f..e4cf1bc1 100644 --- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/dialogs/CommitDialog.java +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/dialogs/CommitDialog.java @@ -83,14 +83,19 @@ public class CommitDialog extends Dialog { Entry indexEntry = index.getEntry(repoPath); if (headEntry == null) { prefix = "Added"; + if (indexEntry.isModified(repositoryMapping.getWorkDir())) + prefix = "Added, index diff"; } else if (indexEntry == null) { - prefix = "Removed(?)"; + prefix = "Removed"; } else if (headExists && !headEntry.getId().equals( indexEntry.getObjectId())) { prefix = "Modified"; - } else - prefix = "Mod., index diff"; + + + if (indexEntry.isModified(repositoryMapping.getWorkDir())) + prefix = "Mod., index diff"; + } } catch (Exception e) { } diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/IndexDiff.java b/org.spearce.jgit/src/org/spearce/jgit/lib/IndexDiff.java new file mode 100644 index 00000000..413d9c55 --- /dev/null +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/IndexDiff.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2007 David Watson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License, version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + */ + +package org.spearce.jgit.lib; + +import java.io.IOException; +import java.util.HashSet; + +import org.spearce.jgit.lib.GitIndex.Entry; + +public class IndexDiff { + private GitIndex index; + private Tree tree; + + public IndexDiff(Tree tree, GitIndex index) { + this.tree = tree; + this.index = index; + } + + public void diff() throws IOException { + for (Entry entry : index.getMembers()) { + String filename = entry.getName(); +// if (checked.contains(filename)) +// continue; + + TreeEntry treeBlob = tree.findBlobMember(filename); + if (treeBlob == null) { + added.add(filename); + } else if (entry.getObjectId() != null && !entry.getObjectId().equals(treeBlob.getId())) { + changed.add(filename); + } + + checked.add(filename); + } + + tree.accept(new TreeVisitor() { + + public void visitSymlink(SymlinkTreeEntry s) throws IOException { + } + + public void visitFile(FileTreeEntry f) throws IOException { + if (checked.contains(f.getFullName())) + return; + removed.add(f.getFullName()); + } + + public void startVisitTree(Tree t) throws IOException { + // TODO Auto-generated method stub + + } + + public void endVisitTree(Tree t) throws IOException { + // TODO Auto-generated method stub + + } + + }); + } + + private HashSet checked = new HashSet(); + private HashSet added = new HashSet(); + private HashSet changed = new HashSet(); + private HashSet removed = new HashSet(); + + public HashSet getAdded() { + return added; + } + + public HashSet getChanged() { + return changed; + } + + public HashSet getRemoved() { + return removed; + } +} diff --git a/org.spearce.jgit/tst/org/spearce/jgit/lib/IndexDiffTest.java b/org.spearce.jgit/tst/org/spearce/jgit/lib/IndexDiffTest.java new file mode 100644 index 00000000..15229c90 --- /dev/null +++ b/org.spearce.jgit/tst/org/spearce/jgit/lib/IndexDiffTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007 David Watson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License, version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + */ + +package org.spearce.jgit.lib; + +import java.io.File; +import java.io.IOException; + +public class IndexDiffTest extends RepositoryTestCase { + public void testAdded() throws IOException { + GitIndex index = new GitIndex(db); + writeTrashFile("file1", "file1"); + writeTrashFile("dir/subfile", "dir/subfile"); + Tree tree = new Tree(db); + + index.add(trash, new File(trash, "file1")); + index.add(trash, new File(trash, "dir/subfile")); + IndexDiff diff = new IndexDiff(tree, index); + diff.diff(); + assertTrue(diff.getAdded().contains("file1")); + assertTrue(diff.getAdded().contains("dir/subfile")); + } + + public void testRemoved() throws IOException { + GitIndex index = new GitIndex(db); + writeTrashFile("file2", "file2"); + writeTrashFile("dir/file3", "dir/file3"); + + Tree tree = new Tree(db); + tree.addFile("file2"); + tree.addFile("dir/file3"); + assertEquals(2, tree.memberCount()); + + IndexDiff diff = new IndexDiff(tree, index); + diff.diff(); + assertTrue(diff.getRemoved().contains("file2")); + assertTrue(diff.getRemoved().contains("dir/file3")); + } + + public void testModified() throws IOException { + GitIndex index = new GitIndex(db); + writeTrashFile("file2", "file2"); + writeTrashFile("dir/file3", "dir/file3"); + index.add(trash, new File(trash, "file2")); + index.add(trash, new File(trash, "dir/file3")); + + Tree tree = new Tree(db); + tree.addFile("file2"); + tree.addFile("dir/file3"); + assertEquals(2, tree.memberCount()); + + IndexDiff diff = new IndexDiff(tree, index); + diff.diff(); + assertTrue(diff.getChanged().contains("file2")); + assertTrue(diff.getChanged().contains("dir/file3")); + } +} -- 2.11.4.GIT