{"thread":{"id":"18109","subject":"[PATCH JGIT] Add \"compare with Git Index\" action.","startedAt":"2009-03-03T14:04:30Z","lastAt":"2009-03-07T00:31:47Z","messageCount":2,"participants":["Yann Simon","Robin Rosenberg"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"106837","messageId":"49AD38EE.5090509@gmail.com","threadId":"18109","inReplyTo":null,"subject":"[PATCH JGIT] Add \"compare with Git Index\" action.","fromName":"Yann Simon","fromEmail":"yann.simon.fr@gmail.com","sentAt":"2009-03-03T14:04:30Z","receivedAt":"2009-03-03T14:04:30Z","isPatch":true,"sender":{"key":"yann.simon.fr@gmail.com","avatar":"https://gravatar.com/avatar/2d926895d27ac988c5c8e591887e5a6a4c7036390403c74fce92519119b887a0?d=mp&s=160"},"body":"In the Compare With... menu, the \"Git Index\" action opens\na diff editor that compares the workspace version of a file and its\nindex version.\n\nThe local file can be modified and saved.\n\nThe staged version can be modified and saved. This updates the index.\nFor this, add methods into GitIndex to allow to specify a content\ndifferent from the file.\n\nSigned-off-by: Yann Simon <yann.simon.fr@gmail.com>\n---\nChange compare to last sent:\nLabels modified according to suggestion from Robin Rosenberg\n\n .../core/internal/storage/GitFileRevision.java     |   11 ++\n org.spearce.egit.ui/plugin.properties              |    3 +\n org.spearce.egit.ui/plugin.xml                     |    7 +\n .../spearce/egit/ui/internal/EditableRevision.java |  157 ++++++++++++++++++++\n .../GitCompareFileRevisionEditorInput.java         |   36 +++--\n .../internal/actions/CompareWithIndexAction.java   |  119 +++++++++++++++\n .../src/org/spearce/jgit/lib/GitIndex.java         |   65 ++++++++\n 7 files changed, 384 insertions(+), 14 deletions(-)\n create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/EditableRevision.java\n create mode 100644 org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CompareWithIndexAction.java\n\ndiff --git a/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/GitFileRevision.java b/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/GitFileRevision.java\nindex 21ba19e..2f23c7d 100644\n--- a/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/GitFileRevision.java\n+++ b/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/GitFileRevision.java\n@@ -49,6 +49,17 @@ public static GitFileRevision inCommit(final Repository db,\n \t\treturn new CommitFileRevision(db, commit, path, blobId);\n \t}\n \n+\t/**\n+\t * @param db\n+\t *            the repository which contains the index to use.\n+\t * @param path\n+\t *            path of the resource in the index\n+\t * @return revision implementation for the given path in the index\n+\t */\n+\tpublic static GitFileRevision inIndex(final Repository db, final String path) {\n+\t\treturn new IndexFileRevision(db, path);\n+\t}\n+\n \tprivate final String path;\n \n \tGitFileRevision(final String fileName) {\ndiff --git a/org.spearce.egit.ui/plugin.properties b/org.spearce.egit.ui/plugin.properties\nindex 58b879f..07d7735 100644\n--- a/org.spearce.egit.ui/plugin.properties\n+++ b/org.spearce.egit.ui/plugin.properties\n@@ -31,6 +31,9 @@ Decorator_description=Shows Git specific information on resources in projects un\n CompareWithRevisionAction_label=Compare With Git Revision\n CompareWithRevisionAction_tooltip=Compare With a Git Revision\n \n+CompareWithIndexAction_label=Git Index\n+CompareWithIndexAction_tooltip=Compare with Git's index version\n+\n ShowResourceInHistoryAction_label=Show in Resource History\n ShowResourceInHistoryAction_tooltip=Show selected files in the resource history view.\n \ndiff --git a/org.spearce.egit.ui/plugin.xml b/org.spearce.egit.ui/plugin.xml\nindex 2f23559..678fd73 100644\n--- a/org.spearce.egit.ui/plugin.xml\n+++ b/org.spearce.egit.ui/plugin.xml\n@@ -108,6 +108,13 @@\n                label=\"%CommitAction_label\"\n                menubarPath=\"team.main/group1\"\n                tooltip=\"%CommitAction_tooltip\"/>\n+         <action\n+               class=\"org.spearce.egit.ui.internal.actions.CompareWithIndexAction\"\n+               id=\"org.spearce.egit.ui.internal.actions.CompareWithIndexAction\"\n+               label=\"%CompareWithIndexAction_label\"\n+               menubarPath=\"compareWithMenu/gitCompareWithGroup\"\n+               tooltip=\"&amp;CompareWithIndexAction_tooltip\">\n+         </action>\n \t  </objectContribution>\n \t  <objectContribution\n          id=\"org.spearce.egit.ui.resetto\"\ndiff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/EditableRevision.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/EditableRevision.java\nnew file mode 100644\nindex 0000000..ee064ef\n--- /dev/null\n+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/EditableRevision.java\n@@ -0,0 +1,157 @@\n+/*\n+ * Copyright (C) 2009, Yann Simon <yann.simon.fr@gmail.com>\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.egit.ui.internal;\n+\n+import java.io.ByteArrayInputStream;\n+import java.io.InputStream;\n+\n+import org.eclipse.compare.IContentChangeListener;\n+import org.eclipse.compare.IContentChangeNotifier;\n+import org.eclipse.compare.IEditableContent;\n+import org.eclipse.compare.ISharedDocumentAdapter;\n+import org.eclipse.compare.ITypedElement;\n+import org.eclipse.compare.internal.ContentChangeNotifier;\n+import org.eclipse.core.runtime.CoreException;\n+import org.eclipse.core.runtime.Platform;\n+import org.eclipse.team.core.history.IFileRevision;\n+import org.eclipse.team.internal.ui.history.FileRevisionTypedElement;\n+import org.eclipse.team.internal.ui.synchronize.EditableSharedDocumentAdapter;\n+\n+/**\n+ * @author simon\n+ *\n+ */\n+public class EditableRevision extends FileRevisionTypedElement implements\n+\t\tITypedElement, IEditableContent, IContentChangeNotifier {\n+\n+\tprivate byte[] modifiedContent;\n+\n+\tprivate ContentChangeNotifier fChangeNotifier;\n+\n+\tprivate EditableSharedDocumentAdapter sharedDocumentAdapter;\n+\n+\t/**\n+\t * @param fileRevision\n+\t */\n+\tpublic EditableRevision(IFileRevision fileRevision) {\n+\t\tsuper(fileRevision);\n+\t}\n+\n+\tpublic boolean isEditable() {\n+\t\treturn true;\n+\t}\n+\n+\tpublic ITypedElement replace(ITypedElement dest, ITypedElement src) {\n+\t\treturn null;\n+\t}\n+\n+\t@Override\n+\tpublic InputStream getContents() throws CoreException {\n+\t\tif (modifiedContent != null) {\n+\t\t\treturn new ByteArrayInputStream(modifiedContent);\n+\t\t}\n+\t\treturn super.getContents();\n+\t}\n+\n+\tpublic void setContent(byte[] newContent) {\n+\t\tmodifiedContent = newContent;\n+\t\tfireContentChanged();\n+\t}\n+\n+\t/**\n+\t * @return the modified content\n+\t */\n+\tpublic byte[] getModifiedContent() {\n+\t\treturn modifiedContent;\n+\t}\n+\n+\tpublic Object getAdapter(Class adapter) {\n+\t\tif (adapter == ISharedDocumentAdapter.class) {\n+\t\t\treturn getSharedDocumentAdapter();\n+\t\t}\n+\t\treturn Platform.getAdapterManager().getAdapter(this, adapter);\n+\t}\n+\n+\tprivate synchronized ISharedDocumentAdapter getSharedDocumentAdapter() {\n+\t\tif (sharedDocumentAdapter == null)\n+\t\t\tsharedDocumentAdapter = new EditableSharedDocumentAdapter(\n+\t\t\t\t\tnew EditableSharedDocumentAdapter.ISharedDocumentAdapterListener() {\n+\t\t\t\t\t\tpublic void handleDocumentConnected() {\n+\t\t\t\t\t\t}\n+\n+\t\t\t\t\t\tpublic void handleDocumentFlushed() {\n+\t\t\t\t\t\t}\n+\n+\t\t\t\t\t\tpublic void handleDocumentDeleted() {\n+\t\t\t\t\t\t}\n+\n+\t\t\t\t\t\tpublic void handleDocumentSaved() {\n+\t\t\t\t\t\t}\n+\n+\t\t\t\t\t\tpublic void handleDocumentDisconnected() {\n+\t\t\t\t\t\t}\n+\t\t\t\t\t});\n+\t\treturn sharedDocumentAdapter;\n+\t}\n+\n+\tpublic void addContentChangeListener(IContentChangeListener listener) {\n+\t\tif (fChangeNotifier == null)\n+\t\t\tfChangeNotifier = new ContentChangeNotifier(this);\n+\t\tfChangeNotifier.addContentChangeListener(listener);\n+\t}\n+\n+\tpublic void removeContentChangeListener(IContentChangeListener listener) {\n+\t\tif (fChangeNotifier != null) {\n+\t\t\tfChangeNotifier.removeContentChangeListener(listener);\n+\t\t\tif (fChangeNotifier.isEmpty())\n+\t\t\t\tfChangeNotifier = null;\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Notifies all registered <code>IContentChangeListener</code>s of a content\n+\t * change.\n+\t */\n+\tprotected void fireContentChanged() {\n+\t\tif (fChangeNotifier == null || fChangeNotifier.isEmpty()) {\n+\t\t\treturn;\n+\t\t}\n+\t\tfChangeNotifier.fireContentChanged();\n+\t}\n+\n+}\ndiff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java\nindex 8aa076f..49d4a42 100644\n--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java\n+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/GitCompareFileRevisionEditorInput.java\n@@ -11,7 +11,6 @@\n import java.lang.reflect.InvocationTargetException;\n \n import org.eclipse.compare.CompareConfiguration;\n-import org.eclipse.compare.CompareEditorInput;\n import org.eclipse.compare.IEditableContent;\n import org.eclipse.compare.IResourceProvider;\n import org.eclipse.compare.ITypedElement;\n@@ -34,13 +33,14 @@\n import org.eclipse.team.internal.ui.Utils;\n import org.eclipse.team.internal.ui.history.FileRevisionTypedElement;\n import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement;\n+import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;\n import org.eclipse.ui.IWorkbenchPage;\n \n /**\n  * The input provider for the compare editor when working on resources\n  * under Git control.\n  */\n-public class GitCompareFileRevisionEditorInput extends CompareEditorInput {\n+public class GitCompareFileRevisionEditorInput extends SaveableCompareEditorInput {\n \n \tprivate ITypedElement left;\n \tprivate ITypedElement right;\n@@ -52,7 +52,7 @@\n \t * @param page\n \t */\n \tpublic GitCompareFileRevisionEditorInput(ITypedElement left, ITypedElement right, IWorkbenchPage page) {\n-\t\tsuper(new CompareConfiguration());\n+\t\tsuper(new CompareConfiguration(), page);\n \t\tthis.left = left;\n \t\tthis.right = right;\n \t}\n@@ -90,9 +90,18 @@ private static void ensureContentsCached(FileRevisionTypedElement left, FileRevi\n \t}\n \n \tprivate boolean isLeftEditable(ICompareInput input) {\n-\t\tObject left = input.getLeft();\n-\t\tif (left instanceof IEditableContent) {\n-\t\t\treturn ((IEditableContent) left).isEditable();\n+\t\tObject tmpLeft = input.getLeft();\n+\t\treturn isEditable(tmpLeft);\n+\t}\n+\n+\tprivate boolean isRightEditable(ICompareInput input) {\n+\t\tObject tmpRight = input.getRight();\n+\t\treturn isEditable(tmpRight);\n+\t}\n+\n+\tprivate boolean isEditable(Object object) {\n+\t\tif (object instanceof IEditableContent) {\n+\t\t\treturn ((IEditableContent) object).isEditable();\n \t\t}\n \t\treturn false;\n \t}\n@@ -326,12 +335,9 @@ private String getContentIdentifier(ITypedElement element){\n \t\treturn TeamUIMessages.CompareFileRevisionEditorInput_2;\n \t}\n \n-//\t/* (non-Javadoc)\n-//\t * @see org.eclipse.team.ui.synchronize.LocalResourceCompareEditorInput#fireInputChange()\n-//\t */\n-//\tprotected void fireInputChange() {\n-//\t\t((DiffNode)getCompareResult()).fireChange();\n-//\t}\n+\t@Override\n+\tprotected void fireInputChange() {\n+\t}\n //\n //\t/* (non-Javadoc)\n //\t * @see org.eclipse.team.ui.synchronize.SaveableCompareEditorInput#contentsCreated()\n@@ -359,10 +365,12 @@ private LocalResourceTypedElement getLocalElement() {\n \t\treturn null;\n \t}\n \n-\tprotected Object prepareInput(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\n+\t@Override\n+\tprotected ICompareInput prepareCompareInput(IProgressMonitor monitor)\n+\t\t\tthrows InvocationTargetException, InterruptedException {\n \t\tICompareInput input = createCompareInput();\n \t\tgetCompareConfiguration().setLeftEditable(isLeftEditable(input));\n-\t\tgetCompareConfiguration().setRightEditable(false);\n+\t\tgetCompareConfiguration().setRightEditable(isRightEditable(input));\n \t\tensureContentsCached(getLeftRevision(), getRightRevision(), monitor);\n \t\tinitLabels(input);\n \t\tsetTitle(NLS.bind(TeamUIMessages.SyncInfoCompareInput_title, new String[] { input.getName() }));\ndiff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CompareWithIndexAction.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CompareWithIndexAction.java\nnew file mode 100644\nindex 0000000..3bc24be\n--- /dev/null\n+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CompareWithIndexAction.java\n@@ -0,0 +1,119 @@\n+/*\n+ * Copyright (C) 2009, Yann Simon <yann.simon.fr@gmail.com>\n+ *\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or\n+ * without modification, are permitted provided that the following\n+ * conditions are met:\n+ *\n+ * - Redistributions of source code must retain the above copyright\n+ *   notice, this list of conditions and the following disclaimer.\n+ *\n+ * - Redistributions in binary form must reproduce the above\n+ *   copyright notice, this list of conditions and the following\n+ *   disclaimer in the documentation and/or other materials provided\n+ *   with the distribution.\n+ *\n+ * - Neither the name of the Git Development Community nor the\n+ *   names of its contributors may be used to endorse or promote\n+ *   products derived from this software without specific prior\n+ *   written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n+ * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,\n+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+package org.spearce.egit.ui.internal.actions;\n+\n+import java.io.File;\n+import java.io.IOException;\n+\n+import org.eclipse.compare.CompareUI;\n+import org.eclipse.compare.IContentChangeListener;\n+import org.eclipse.compare.IContentChangeNotifier;\n+import org.eclipse.compare.ITypedElement;\n+import org.eclipse.core.resources.IFile;\n+import org.eclipse.core.resources.IResource;\n+import org.eclipse.jface.action.IAction;\n+import org.eclipse.team.core.history.IFileRevision;\n+import org.eclipse.team.internal.ui.Utils;\n+import org.eclipse.team.ui.synchronize.SaveableCompareEditorInput;\n+import org.spearce.egit.core.internal.storage.GitFileRevision;\n+import org.spearce.egit.core.project.RepositoryMapping;\n+import org.spearce.egit.ui.internal.EditableRevision;\n+import org.spearce.egit.ui.internal.GitCompareFileRevisionEditorInput;\n+import org.spearce.jgit.lib.GitIndex;\n+import org.spearce.jgit.lib.Repository;\n+\n+/**\n+ * The \"compare with index\" action. This action opens a diff editor comparing\n+ * the file as found in the working directory and the version found in the index\n+ * of the repository.\n+ */\n+@SuppressWarnings(\"restriction\")\n+public class CompareWithIndexAction extends RepositoryAction {\n+\n+\t@Override\n+\tpublic void execute(IAction action) {\n+\t\tfinal IResource resource = getSelectedResources()[0];\n+\t\tfinal RepositoryMapping mapping = RepositoryMapping.getMapping(resource.getProject());\n+\t\tfinal Repository repository = mapping.getRepository();\n+\t\tfinal String gitPath = mapping.getRepoRelativePath(resource);\n+\n+\t\tfinal IFileRevision nextFile = GitFileRevision.inIndex(repository, gitPath);\n+\n+\t\tfinal IFile baseFile = (IFile) resource;\n+\t\tfinal ITypedElement base = SaveableCompareEditorInput.createFileElement(baseFile);\n+\n+\t\tfinal EditableRevision next = new EditableRevision(nextFile);\n+\n+\t\tIContentChangeListener listener = new IContentChangeListener() {\n+\t\t\tpublic void contentChanged(IContentChangeNotifier source) {\n+\t\t\t\tfinal byte[] newContent = next.getModifiedContent();\n+\t\t\t\ttry {\n+\t\t\t\t\tfinal GitIndex index = repository.getIndex();\n+\t\t\t\t\tfinal File file = new File(baseFile.getLocation().toString());\n+\t\t\t\t\tindex.add(mapping.getWorkDir(), file, newContent);\n+\t\t\t\t} catch (IOException e) {\n+\t\t\t\t\tUtils.handleError(getTargetPart().getSite().getShell(), e,\n+\t\t\t\t\t\t\t\"Error during adding to index\",\n+\t\t\t\t\t\t\t\"Error during adding to index\");\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t};\n+\n+\t\tnext.addContentChangeListener(listener);\n+\n+\t\tfinal GitCompareFileRevisionEditorInput in = new GitCompareFileRevisionEditorInput(\n+\t\t\t\tbase, next, null);\n+\t\tCompareUI.openCompareEditor(in);\n+\t}\n+\n+\t@Override\n+\tpublic boolean isEnabled() {\n+\t\tfinal IResource[] selectedResources = getSelectedResources();\n+\t\tif (selectedResources.length != 1)\n+\t\t\treturn false;\n+\n+\t\tfinal IResource resource = selectedResources[0];\n+\t\tif (!(resource instanceof IFile)) {\n+\t\t\treturn false;\n+\t\t}\n+\t\tfinal RepositoryMapping mapping = RepositoryMapping.getMapping(resource.getProject());\n+\t\treturn mapping != null;\n+\t}\n+\n+}\n\\ No newline at end of file\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/GitIndex.java b/org.spearce.jgit/src/org/spearce/jgit/lib/GitIndex.java\nindex 920a9c9..21b495a 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/lib/GitIndex.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/lib/GitIndex.java\n@@ -170,6 +170,30 @@ public Entry add(File wd, File f) throws IOException {\n \t}\n \n \t/**\n+\t * Add the content of a file to the index.\n+\t *\n+\t * @param wd\n+\t *            workdir\n+\t * @param f\n+\t *            the file\n+\t * @param content\n+\t *            content of the file\n+\t * @return a new or updated index entry for the path represented by f\n+\t * @throws IOException\n+\t */\n+\tpublic Entry add(File wd, File f, byte[] content) throws IOException {\n+\t\tbyte[] key = makeKey(wd, f);\n+\t\tEntry e = entries.get(key);\n+\t\tif (e == null) {\n+\t\t\te = new Entry(key, f, 0, content);\n+\t\t\tentries.put(key, e);\n+\t\t} else {\n+\t\t\te.update(f, content);\n+\t\t}\n+\t\treturn e;\n+\t}\n+\n+\t/**\n \t * Remove a path from the index.\n \t *\n \t * @param wd\n@@ -360,6 +384,25 @@ Entry(byte[] key, File f, int stage)\n \t\t\tflags = (short) ((stage << 12) | name.length); // TODO: fix flags\n \t\t}\n \n+\t\tEntry(byte[] key, File f, int stage, byte[] newContent)\n+\t\t\t\tthrows IOException {\n+\t\t\tctime = f.lastModified() * 1000000L;\n+\t\t\tmtime = ctime; // we use same here\n+\t\t\tdev = -1;\n+\t\t\tino = -1;\n+\t\t\tif (config_filemode() && File_canExecute(f))\n+\t\t\t\tmode = FileMode.EXECUTABLE_FILE.getBits();\n+\t\t\telse\n+\t\t\t\tmode = FileMode.REGULAR_FILE.getBits();\n+\t\t\tuid = -1;\n+\t\t\tgid = -1;\n+\t\t\tsize = newContent.length;\n+\t\t\tObjectWriter writer = new ObjectWriter(db);\n+\t\t\tsha1 = writer.writeBlob(newContent);\n+\t\t\tname = key;\n+\t\t\tflags = (short) ((stage << 12) | name.length); // TODO: fix flags\n+\t\t}\n+\n \t\tEntry(TreeEntry f, int stage) {\n \t\t\tctime = -1; // hmm\n \t\t\tmtime = -1;\n@@ -433,6 +476,28 @@ public boolean update(File f) throws IOException {\n \t\t\treturn modified;\n \t\t}\n \n+\t\t/**\n+\t\t * Update this index entry with stat and SHA-1 information if it looks\n+\t\t * like the file has been modified in the workdir.\n+\t\t *\n+\t\t * @param f\n+\t\t *            file in work dir\n+\t\t * @param newContent\n+\t\t *            the new content of the file\n+\t\t * @return true if a change occurred\n+\t\t * @throws IOException\n+\t\t */\n+\t\tpublic boolean update(File f, byte[] newContent) throws IOException {\n+\t\t\tboolean modified = false;\n+\t\t\tsize = newContent.length;\n+\t\t\tObjectWriter writer = new ObjectWriter(db);\n+\t\t\tObjectId newsha1 = sha1 = writer.writeBlob(newContent);\n+\t\t\tif (!newsha1.equals(sha1))\n+\t\t\t\tmodified = true;\n+\t\t\tsha1 = newsha1;\n+\t\t\treturn modified;\n+\t\t}\n+\n \t\tvoid write(ByteBuffer buf) {\n \t\t\tint startposition = buf.position();\n \t\t\tbuf.putInt((int) (ctime / 1000000000L));\n-- \n1.6.1.2\n"},{"id":"107257","messageId":"200903070131.48136.robin.rosenberg.lists@dewire.com","threadId":"18109","inReplyTo":"49AD38EE.5090509@gmail.com","subject":"Re: [PATCH JGIT] Add \"compare with Git Index\" action.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2009-03-07T00:31:47Z","receivedAt":"2009-03-07T00:31:47Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"tisdag 03 mars 2009 15:04:30 skrev Yann Simon <yann.simon.fr@gmail.com>:\n> In the Compare With... menu, the \"Git Index\" action opens\n> a diff editor that compares the workspace version of a file and its\n> index version.\n> \n> The local file can be modified and saved.\n> \n> The staged version can be modified and saved. This updates the index.\n> For this, add methods into GitIndex to allow to specify a content\n> different from the file.\n\nSaving the index version does not work here. No effect whatsoever.\n\n-- robin\n"}]}