Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CreatePatchOperationTest.java167
-rw-r--r--org.eclipse.egit.core/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java6
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties2
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CompareCoreUtils.java80
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java208
-rw-r--r--org.eclipse.egit.ui/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java58
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java3
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java138
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreatePatchHandler.java7
14 files changed, 512 insertions, 176 deletions
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CreatePatchOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CreatePatchOperationTest.java
new file mode 100644
index 0000000000..4a56181900
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CreatePatchOperationTest.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2011, Tasktop Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benjamin Muskalla (Tasktop Technologies) - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.core.test.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.op.CreatePatchOperation;
+import org.eclipse.egit.core.test.GitTestCase;
+import org.eclipse.egit.core.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CreatePatchOperationTest extends GitTestCase {
+
+ private static final String SIMPLE_GIT_PATCH_CONTENT = "From 6dcd097c7d39e9ba0b31a380981d3fb46017d6c2 Sat, 23 Jul 2011 20:33:24 -0330\n"
+ + "From: J. Git <j.git@egit.org>\n"
+ + "Date: Sat, 15 Aug 2009 20:12:58 -0330\n"
+ + "Subject: [PATCH] 2nd commit\n"
+ + "\n"
+ + "diff --git a/test-file b/test-file\n"
+ + "index e69de29..eb5f2c9 100644\n"
+ + "--- a/test-file\n"
+ + "+++ b/test-file\n"
+ + "@@ -0,0 +1 @@\n"
+ + "+another line\n"
+ + "\\ No newline at end of file";
+
+ private static final String SIMPLE_PATCH_CONTENT = "diff --git a/test-file b/test-file\n"
+ + "index e69de29..eb5f2c9 100644\n"
+ + "--- a/test-file\n"
+ + "+++ b/test-file\n"
+ + "@@ -0,0 +1 @@\n"
+ + "+another line\n"
+ + "\\ No newline at end of file";
+
+ private RevCommit commit;
+
+ private File file;
+
+ private TestRepository testRepository;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ gitDir = new File(project.getProject().getLocationURI().getPath(),
+ Constants.DOT_GIT);
+ testRepository = new TestRepository(gitDir);
+ testRepository.connect(project.getProject());
+
+ file = testRepository.createFile(project.getProject(), "test-file");
+
+ commit = testRepository.addAndCommit(project.getProject(), file,
+ "new file");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ testRepository.dispose();
+ super.tearDown();
+ }
+
+ @Test
+ public void testSimpleGitPatch() throws Exception {
+ RevCommit secondCommit = testRepository.appendContentAndCommit(
+ project.getProject(), file, "another line", "2nd commit");
+
+ CreatePatchOperation operation = new CreatePatchOperation(
+ testRepository.getRepository(), secondCommit);
+
+ operation.execute(new NullProgressMonitor());
+
+ String patchContent = operation.getPatchContent();
+ assertNotNull(patchContent);
+ assertGitPatch(SIMPLE_GIT_PATCH_CONTENT, patchContent);
+ }
+
+ @Test
+ public void testSimplePatch() throws Exception {
+ RevCommit secondCommit = testRepository.appendContentAndCommit(
+ project.getProject(), file, "another line", "2nd commit");
+
+ CreatePatchOperation operation = new CreatePatchOperation(
+ testRepository.getRepository(), secondCommit);
+
+ operation.useGitFormat(false);
+ operation.execute(new NullProgressMonitor());
+
+ String patchContent = operation.getPatchContent();
+ assertNotNull(patchContent);
+ assertPatch(SIMPLE_PATCH_CONTENT, patchContent);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testFirstCommit() throws Exception {
+ CreatePatchOperation operation = new CreatePatchOperation(
+ testRepository.getRepository(), commit);
+
+ operation.execute(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNullCommit() throws Exception {
+ new CreatePatchOperation(testRepository.getRepository(), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNullRepo() throws Exception {
+ new CreatePatchOperation(null, commit);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testExecuteFirst() throws Exception {
+ CreatePatchOperation operation = new CreatePatchOperation(
+ testRepository.getRepository(), commit);
+ operation.getPatchContent();
+ }
+
+ @Test
+ public void testNullMonitor() throws Exception {
+ RevCommit secondCommit = testRepository.appendContentAndCommit(
+ project.getProject(), file, "another line", "2nd commit");
+ CreatePatchOperation operation = new CreatePatchOperation(
+ testRepository.getRepository(), secondCommit);
+ operation.execute(null);
+ }
+
+ @Test
+ public void testSuggestName() throws Exception {
+ RevCommit aCommit = testRepository.appendContentAndCommit(
+ project.getProject(), file, "another line", "2nd commit");
+ assertEquals("2nd-commit.patch", CreatePatchOperation.suggestFileName(aCommit));
+
+ aCommit = testRepository.appendContentAndCommit(
+ project.getProject(), file, "another line", "[findBugs] Change visibility of repositoryFile to package");
+ assertEquals("findBugs-Change-visibility-of-repositoryFile-to-pack.patch", CreatePatchOperation.suggestFileName(aCommit));
+
+ aCommit = testRepository.appendContentAndCommit(
+ project.getProject(), file, "another line", "Add collapse/expand all utility method for tree viewers.");
+ assertEquals("Add-collapse-expand-all-utility-method-for-tree-view.patch", CreatePatchOperation.suggestFileName(aCommit));
+ }
+
+ private void assertGitPatch(String expected, String actual) {
+ assertEquals(expected.substring(0,45), actual.substring(0,45));
+ assertEquals(expected.substring(expected.indexOf("\n")), actual.substring(actual.indexOf("\n")));
+ }
+
+ private void assertPatch(String expected, String actual) {
+ assertEquals(expected, actual);
+ }
+
+}
diff --git a/org.eclipse.egit.core/META-INF/MANIFEST.MF b/org.eclipse.egit.core/META-INF/MANIFEST.MF
index a033530dcf..328a0408d9 100644
--- a/org.eclipse.egit.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core/META-INF/MANIFEST.MF
@@ -12,7 +12,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)",
org.eclipse.equinox.security;bundle-version="[1.0.0,2.0.0)"
Export-Package: org.eclipse.egit.core;version="1.1.0",
- org.eclipse.egit.core.internal;version="1.1.0";x-internal:=true,
+ org.eclipse.egit.core.internal;version="1.1.0";x-friends:="org.eclipse.egit.ui",
org.eclipse.egit.core.internal.storage;version="1.1.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.core.test",
org.eclipse.egit.core.internal.trace;version="1.1.0";x-internal:=true,
org.eclipse.egit.core.internal.util;version="1.1.0";x-friends:="org.eclipse.egit.ui",
@@ -25,13 +25,15 @@ Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.eclipse.jgit.api;version="[1.1.0,1.2.0)",
org.eclipse.jgit.api.errors;version="[1.1.0,1.2.0)",
+ org.eclipse.jgit.diff;version="[1.1.0,1.2.0)",
org.eclipse.jgit.dircache;version="[1.1.0,1.2.0)",
org.eclipse.jgit.errors;version="[1.1.0,1.2.0)",
org.eclipse.jgit.lib;version="[1.1.0,1.2.0)",
org.eclipse.jgit.merge;version="[1.1.0,1.2.0)",
+ org.eclipse.jgit.patch;version="[1.1.0,1.2.0)",
org.eclipse.jgit.revwalk;version="[1.1.0,1.2.0)",
- org.eclipse.jgit.storage.file;version="[1.1.0,1.2.0)",
org.eclipse.jgit.revwalk.filter;version="[1.1.0,1.2.0)",
+ org.eclipse.jgit.storage.file;version="[1.1.0,1.2.0)",
org.eclipse.jgit.transport;version="[1.1.0,1.2.0)",
org.eclipse.jgit.treewalk;version="[1.1.0,1.2.0)",
org.eclipse.jgit.treewalk.filter;version="[1.1.0,1.2.0)",
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
index f827a6851a..2a3b9cda65 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
@@ -198,6 +198,12 @@ public class CoreText extends NLS {
public static String CreateLocalBranchOperation_CreatingBranchMessage;
/** */
+ public static String CreatePatchOperation_commitRequired;
+
+ /** */
+ public static String CreatePatchOperation_repoRequired;
+
+ /** */
public static String IndexFileRevision_errorLookingUpPath;
/** */
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
index 6eba656c2a..06dbc274c5 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
@@ -81,6 +81,8 @@ CloneOperation_initializingRepository=Initializing local repository
CloneOperation_title=Cloning from {0}
CloneOperation_writingIndex=Writing index
CreateLocalBranchOperation_CreatingBranchMessage=Creating branch {0}
+CreatePatchOperation_commitRequired=A commit is required to create a patch
+CreatePatchOperation_repoRequired=A repository is required to create a patch
IndexFileRevision_errorLookingUpPath=IO error looking up path {0} in index.
IndexFileRevision_indexEntryNotFound=Git index entry for path {1} not found
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CompareCoreUtils.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CompareCoreUtils.java
new file mode 100644
index 0000000000..2e2eab7530
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CompareCoreUtils.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2010, SAP AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Lay (SAP AG) - initial implementation
+ * Benjamin Muskalla (Tasktop Technologies) - moved into Core for reusability
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import org.eclipse.core.resources.IEncodedStorage;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Utility class for compare-related functionality
+ */
+public class CompareCoreUtils {
+
+ /**
+ * Determine the encoding used by Eclipse for the resource which belongs to
+ * repoPath in the eclipse workspace or null if no resource is found
+ *
+ * @param db
+ * the repository
+ * @param repoPath
+ * the path in the git repository
+ * @return the encoding used in eclipse for the resource or null if
+ *
+ */
+ public static String getResourceEncoding(Repository db, String repoPath) {
+ if (db.isBare())
+ return null;
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IWorkspaceRoot root = workspace.getRoot();
+ IPath absolutePath = new Path(db.getWorkTree().getAbsolutePath())
+ .append(repoPath);
+ IResource resource = root.getFileForLocation(absolutePath);
+ if (resource == null)
+ return null;
+
+ return getResourceEncoding(resource);
+ }
+
+ /**
+ * Determine the encoding used by eclipse for the resource.
+ *
+ * @param resource
+ * must be an instance of IEncodedStorage
+ * @return the encoding used in Eclipse for the resource if found or null
+ */
+ public static String getResourceEncoding(IResource resource) {
+ // Get the encoding for the current version. As a matter of
+ // principle one might want to use the eclipse settings for the
+ // version we are retrieving as that may be defined by the
+ // project settings, but there is no historic API for this.
+ String charset;
+ IEncodedStorage encodedStorage = ((IEncodedStorage) resource);
+ try {
+ charset = encodedStorage.getCharset();
+ if (charset == null)
+ charset = resource.getParent().getDefaultCharset();
+ } catch (CoreException e) {
+ charset = Constants.CHARACTER_ENCODING;
+ }
+ return charset;
+ }
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java
new file mode 100644
index 0000000000..a5b91b49cd
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2010, SAP AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Lay (SAP AG) - initial implementation
+ * Benjamin Muskalla (Tasktop Technologies) - extract into operation
+ *******************************************************************************/
+package org.eclipse.egit.core.op;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Locale;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.CoreText;
+import org.eclipse.egit.core.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.CompareCoreUtils;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+/**
+ * Creates a patch for a specific commit
+ */
+public class CreatePatchOperation implements IEGitOperation {
+
+ private final RevCommit commit;
+
+ private final Repository repository;
+
+ private boolean useGitFormat = true;
+
+ // the encoding for the currently processed file
+ private String currentEncoding = null;
+
+ private String patchContent;
+
+ /**
+ * Creates the new operation.
+ *
+ * @param repository
+ * @param commit
+ */
+ public CreatePatchOperation(Repository repository, RevCommit commit) {
+ if (repository == null)
+ throw new IllegalArgumentException(
+ CoreText.CreatePatchOperation_repoRequired);
+ if (commit == null)
+ throw new IllegalArgumentException(
+ CoreText.CreatePatchOperation_commitRequired);
+ this.repository = repository;
+ this.commit = commit;
+ }
+
+ public void execute(IProgressMonitor monitor) throws CoreException {
+ EclipseGitProgressTransformer gitMonitor;
+ if (monitor == null)
+ gitMonitor = new EclipseGitProgressTransformer(
+ new NullProgressMonitor());
+ else
+ gitMonitor = new EclipseGitProgressTransformer(monitor);
+
+ final StringBuilder sb = new StringBuilder();
+ final DiffFormatter diffFmt = new DiffFormatter(
+ new ByteArrayOutputStream() {
+
+ @Override
+ public synchronized void write(byte[] b, int off, int len) {
+ super.write(b, off, len);
+ if (currentEncoding == null)
+ sb.append(toString());
+ else try {
+ sb.append(toString(currentEncoding));
+ } catch (UnsupportedEncodingException e) {
+ sb.append(toString());
+ }
+ reset();
+ }
+ });
+
+ diffFmt.setProgressMonitor(gitMonitor);
+
+ RevCommit[] parents = commit.getParents();
+ if (parents.length > 1)
+ throw new IllegalStateException(
+ "Cannot create patch for merge commit"); //$NON-NLS-1$
+
+ if (parents.length == 0)
+ throw new IllegalStateException(
+ "Cannot create patch for first commit"); //$NON-NLS-1$
+
+ if (useGitFormat)
+ writeGitPatchHeader(sb);
+
+ try {
+ diffFmt.setRepository(repository);
+ List<DiffEntry> diffs = diffFmt.scan(parents[0].getId(), commit.getId());
+ for (DiffEntry ent : diffs) {
+ String path;
+ if (ChangeType.DELETE.equals(ent.getChangeType()))
+ path = ent.getOldPath();
+ else
+ path = ent.getNewPath();
+ currentEncoding = CompareCoreUtils.getResourceEncoding(repository, path);
+ diffFmt.format(ent);
+ }
+ } catch (IOException e) {
+ Activator.logError("Patch file could not be written", e); //$NON-NLS-1$
+ }
+
+ patchContent = sb.toString();
+ // trim newline
+ if (patchContent.endsWith("\n")) //$NON-NLS-1$
+ patchContent = patchContent.substring(0, patchContent.length() - 1);
+ }
+
+ /**
+ * Retrieves the content of the requested patch
+ *
+ * @return the content of the patch
+ */
+ public String getPatchContent() {
+ if (patchContent == null)
+ throw new IllegalStateException(
+ "#execute needs to be called before this method."); //$NON-NLS-1$
+ return patchContent;
+ }
+
+ private void writeGitPatchHeader(StringBuilder sb) {
+ final SimpleDateFormat dtfmt;
+ dtfmt = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US); //$NON-NLS-1$
+ dtfmt.setTimeZone(commit.getAuthorIdent().getTimeZone());
+ sb.append("From").append(" ") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(commit.getId().getName()).append(" ") //$NON-NLS-1$
+ .append(dtfmt.format(Long.valueOf(System.currentTimeMillis())))
+ .append("\n"); //$NON-NLS-1$
+ sb.append("From") //$NON-NLS-1$
+ .append(": ") //$NON-NLS-1$
+ .append(commit.getAuthorIdent().getName())
+ .append(" <").append(commit.getAuthorIdent().getEmailAddress()) //$NON-NLS-1$
+ .append(">\n"); //$NON-NLS-1$
+ sb.append("Date").append(": ") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(dtfmt.format(commit.getAuthorIdent().getWhen()))
+ .append("\n"); //$NON-NLS-1$
+ sb.append("Subject").append(": [PATCH] ") //$NON-NLS-1$ //$NON-NLS-2$
+ .append(commit.getShortMessage());
+
+ String message = commit.getFullMessage().substring(
+ commit.getShortMessage().length());
+ sb.append(message).append("\n\n"); //$NON-NLS-1$
+ }
+
+ /**
+ * Decides whether to use the git format for patches.
+ *
+ * @param useFormat
+ */
+ public void useGitFormat(boolean useFormat) {
+ this.useGitFormat = useFormat;
+ }
+
+ /**
+ * Suggests a file name for the patch given the commit.
+ *
+ * @param commit
+ * @return a file name for a patch
+ */
+ public static String suggestFileName(RevCommit commit) {
+ String name = commit.getShortMessage();
+
+ name = name.trim();
+ StringBuilder filteredBuilder = new StringBuilder();
+ char[] charArray = name.toCharArray();
+ for (char c : charArray) {
+ if(Character.isLetter(c) || Character.isDigit(c))
+ filteredBuilder.append(c);
+ if(Character.isWhitespace(c) || c == '/')
+ filteredBuilder.append("-"); //$NON-NLS-1$
+ }
+ name = filteredBuilder.toString();
+ if (name.length() > 52)
+ name = name.substring(0, 52);
+ while (name.endsWith(".")) //$NON-NLS-1$
+ name = name.substring(0, name.length() - 1);
+ name = name.concat(".patch"); //$NON-NLS-1$
+
+ return name;
+ }
+
+ public ISchedulingRule getSchedulingRule() {
+ return null;
+ }
+
+}
diff --git a/org.eclipse.egit.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
index 884e3fe450..20cd6998a7 100644
--- a/org.eclipse.egit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
@@ -32,6 +32,7 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.4.0,4.0.0)",
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.eclipse.egit.core;version="[1.1.0,1.2.0)",
+ org.eclipse.egit.core.internal;version="[1.1.0,1.2.0)",
org.eclipse.egit.core.internal.storage;version="[1.1.0,1.2.0)",
org.eclipse.egit.core.internal.util;version="[1.1.0,1.2.0)",
org.eclipse.egit.core.op;version="[1.1.0,1.2.0)",
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
index f6c16e9fa5..018e9a9427 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
@@ -18,22 +18,17 @@ import java.io.IOException;
import org.eclipse.compare.CompareEditorInput;
import org.eclipse.compare.CompareUI;
import org.eclipse.compare.ITypedElement;
-import org.eclipse.core.resources.IEncodedStorage;
import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.egit.core.internal.CompareCoreUtils;
import org.eclipse.egit.core.internal.storage.GitFileRevision;
import org.eclipse.egit.core.internal.storage.WorkingTreeFileRevision;
import org.eclipse.egit.core.internal.storage.WorkspaceFileRevision;
@@ -114,7 +109,7 @@ public class CompareUtils {
IFileRevision nextFile = getFileRevision(gitPath, commit, db,
blobId);
if (nextFile != null) {
- String encoding = getResourceEncoding(db, gitPath);
+ String encoding = CompareCoreUtils.getResourceEncoding(db, gitPath);
right = new FileRevisionTypedElement(nextFile, encoding);
}
} catch (IOException e) {
@@ -179,55 +174,6 @@ public class CompareUtils {
}
/**
- * Determine the encoding used by Eclipse for the resource which belongs to
- * repoPath in the eclipse workspace or null if no resource is found
- *
- * @param db
- * the repository
- * @param repoPath
- * the path in the git repository
- * @return the encoding used in eclipse for the resource or null if
- *
- */
- public static String getResourceEncoding(Repository db, String repoPath) {
- if (db.isBare())
- return null;
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- IWorkspaceRoot root = workspace.getRoot();
- IPath absolutePath = new Path(db.getWorkTree().getAbsolutePath())
- .append(repoPath);
- IResource resource = root.getFileForLocation(absolutePath);
- if (resource == null)
- return null;
-
- return getResourceEncoding(resource);
- }
-
- /**
- * Determine the encoding used by eclipse for the resource.
- *
- * @param resource
- * must be an instance of IEncodedStorage
- * @return the encoding used in Eclipse for the resource if found or null
- */
- public static String getResourceEncoding(IResource resource) {
- // Get the encoding for the current version. As a matter of
- // principle one might want to use the eclipse settings for the
- // version we are retrieving as that may be defined by the
- // project settings, but there is no historic API for this.
- String charset;
- IEncodedStorage encodedStorage = ((IEncodedStorage) resource);
- try {
- charset = encodedStorage.getCharset();
- if (charset == null)
- charset = resource.getParent().getDefaultCharset();
- } catch (CoreException e) {
- charset = Constants.CHARACTER_ENCODING;
- }
- return charset;
- }
-
- /**
* @param element
* @param adapterType
* @param load
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java
index 82ef5bb01c..d05931c420 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffStyleRangeFormatter.java
@@ -15,7 +15,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
-import org.eclipse.egit.ui.internal.CompareUtils;
+import org.eclipse.egit.core.internal.CompareCoreUtils;
import org.eclipse.egit.ui.internal.commit.DiffStyleRangeFormatter.DiffStyleRange.Type;
import org.eclipse.egit.ui.internal.history.FileDiff;
import org.eclipse.jface.text.BadLocationException;
@@ -159,7 +159,7 @@ public class DiffStyleRangeFormatter extends DiffFormatter {
*/
public DiffStyleRangeFormatter write(Repository repository, FileDiff diff)
throws IOException {
- this.stream.charset = CompareUtils.getResourceEncoding(repository,
+ this.stream.charset = CompareCoreUtils.getResourceEncoding(repository,
diff.getPath());
diff.outputDiff(null, repository, this, true);
flush();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java
index af6e24ad18..cf61b79356 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java
@@ -14,10 +14,10 @@ import java.util.WeakHashMap;
import org.eclipse.core.resources.IResource;
import org.eclipse.egit.core.GitProvider;
+import org.eclipse.egit.core.internal.CompareCoreUtils;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIText;
-import org.eclipse.egit.ui.internal.CompareUtils;
import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
import org.eclipse.jface.text.Document;
import org.eclipse.jgit.events.ListenerHandle;
@@ -172,7 +172,7 @@ class GitDocument extends Document implements RefsChangedListener {
ObjectLoader loader = repository.open(id, Constants.OBJ_BLOB);
byte[] bytes = loader.getBytes();
String charset;
- charset = CompareUtils.getResourceEncoding(resource);
+ charset = CompareCoreUtils.getResourceEncoding(resource);
// Finally we could consider validating the content with respect
// to the content. We don't do that here.
String s = new String(bytes, charset);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java
index c820fb6149..c7830e9eb8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java
@@ -35,6 +35,7 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.egit.core.AdaptableFileTreeIterator;
+import org.eclipse.egit.core.internal.CompareCoreUtils;
import org.eclipse.egit.core.internal.storage.GitFileRevision;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.ui.Activator;
@@ -256,7 +257,7 @@ public class CompareTreeView extends ViewPart {
UIText.CompareTreeView_ItemNotFoundInVersionMessage,
res.getName(), getCompareVersion()));
} else {
- String encoding = CompareUtils.getResourceEncoding(res);
+ String encoding = CompareCoreUtils.getResourceEncoding(res);
right = new FileRevisionTypedElement(rightRevision, encoding);
}
GitCompareFileRevisionEditorInput compareInput = new GitCompareFileRevisionEditorInput(
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
index acd9097cac..4e751b642e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
@@ -31,10 +31,10 @@ import java.util.regex.Pattern;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.egit.core.internal.CompareCoreUtils;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.UIText;
-import org.eclipse.egit.ui.internal.CompareUtils;
import org.eclipse.egit.ui.internal.history.CommitMessageViewer.ObjectLink;
import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
import org.eclipse.jgit.diff.DiffFormatter;
@@ -410,7 +410,7 @@ public class CommitInfoBuilder {
String path = currentDiff.getPath();
monitor.setTaskName(NLS.bind(
UIText.CommitMessageViewer_BuildDiffTaskName, path));
- currentEncoding[0] = CompareUtils.getResourceEncoding(db,
+ currentEncoding[0] = CompareCoreUtils.getResourceEncoding(db,
path);
d.append(formatPathLine(path)).append(LF);
currentDiff.outputDiff(d, db, diffFmt, true);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
index 9caba48d1d..eb6d172f14 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
@@ -11,25 +11,20 @@
*******************************************************************************/
package org.eclipse.egit.ui.internal.history;
-import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
-import java.net.URLEncoder;
-import java.text.SimpleDateFormat;
-import java.util.Locale;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.op.CreatePatchOperation;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIIcons;
import org.eclipse.egit.ui.UIText;
-import org.eclipse.egit.ui.internal.CompareUtils;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.operation.IRunnableWithProgress;
@@ -37,10 +32,8 @@ import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
@@ -65,17 +58,12 @@ public class GitCreatePatchWizard extends Wizard {
private RevCommit commit;
- private TreeWalk walker;
-
private Repository db;
private LocationPage locationPage;
private OptionsPage optionsPage;
- // the encoding for the currently processed file
- private String currentEncoding = null;
-
// The initial size of this wizard.
private final static int INITIAL_WIDTH = 300;
@@ -85,14 +73,12 @@ public class GitCreatePatchWizard extends Wizard {
*
* @param part
* @param commit
- * @param walker
* @param db
*/
public static void run(IWorkbenchPart part, final RevCommit commit,
- TreeWalk walker, Repository db) {
+ Repository db) {
final String title = UIText.GitCreatePatchWizard_CreatePatchTitle;
- final GitCreatePatchWizard wizard = new GitCreatePatchWizard(commit,
- walker, db);
+ final GitCreatePatchWizard wizard = new GitCreatePatchWizard(commit, db);
wizard.setWindowTitle(title);
WizardDialog dialog = new WizardDialog(part.getSite().getShell(),
wizard);
@@ -103,15 +89,13 @@ public class GitCreatePatchWizard extends Wizard {
/**
* Creates a wizard which is used to export the changes introduced by a
- * commit, filtered by a TreeWalk
+ * commit.
*
* @param commit
- * @param walker
* @param db
*/
- public GitCreatePatchWizard(RevCommit commit, TreeWalk walker, Repository db) {
+ public GitCreatePatchWizard(RevCommit commit, Repository db) {
this.commit = commit;
- this.walker = walker;
this.db = db;
}
@@ -133,59 +117,30 @@ public class GitCreatePatchWizard extends Wizard {
@Override
public boolean performFinish() {
- final boolean isGit = optionsPage.gitFormat.getSelection();
+ final CreatePatchOperation operation = new CreatePatchOperation(db,
+ commit);
+ operation.useGitFormat(optionsPage.gitFormat.getSelection());
+
final boolean isFile = locationPage.fsRadio.getSelection();
final String fileName = locationPage.fsPathText.getText();
try {
getContainer().run(true, true, new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor) {
- final StringBuilder sb = new StringBuilder();
- final DiffFormatter diffFmt = new DiffFormatter(
- new BufferedOutputStream(new ByteArrayOutputStream() {
-
- @Override
- public synchronized void write(byte[] b, int off, int len) {
- super.write(b, off, len);
- if (currentEncoding == null)
- sb.append(toString());
- else try {
- sb.append(toString(currentEncoding));
- } catch (UnsupportedEncodingException e) {
- sb.append(toString());
- }
- reset();
- }
-
- }));
-
- if (isGit)
- writeGitPatchHeader(sb);
+ public void run(IProgressMonitor monitor)
+ throws InvocationTargetException {
try {
- FileDiff[] diffs = FileDiff.compute(walker, commit);
- for (FileDiff diff : diffs) {
- currentEncoding = CompareUtils.
- getResourceEncoding(db, diff.getPath());
- diff.outputDiff(sb, db, diffFmt, isGit);
- diffFmt.flush();
- }
+ operation.execute(monitor);
+ String content = operation.getPatchContent();
if (isFile) {
- Writer output = new BufferedWriter(new FileWriter(
- fileName));
- try {
- // FileWriter always assumes default encoding is
- // OK!
- output.write(sb.toString());
- } finally {
- output.close();
- }
+ writeToFile(fileName, content);
} else {
- copyToClipboard(sb.toString());
+ copyToClipboard(content);
}
} catch (IOException e) {
- Activator
- .logError("Patch file could not be written", e); //$NON-NLS-1$
+ throw new InvocationTargetException(e);
+ } catch (CoreException e) {
+ throw new InvocationTargetException(e);
}
}
});
@@ -202,31 +157,6 @@ public class GitCreatePatchWizard extends Wizard {
return true;
}
- private void writeGitPatchHeader(StringBuilder sb) {
-
- final SimpleDateFormat dtfmt;
- dtfmt = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US); //$NON-NLS-1$
- dtfmt.setTimeZone(commit.getAuthorIdent().getTimeZone());
- sb.append("From").append(" ") //$NON-NLS-1$ //$NON-NLS-2$
- .append(commit.getId().getName()).append(" ") //$NON-NLS-1$
- .append(dtfmt.format(Long.valueOf(System.currentTimeMillis())))
- .append("\n"); //$NON-NLS-1$
- sb.append("From") //$NON-NLS-1$
- .append(": ") //$NON-NLS-1$
- .append(commit.getAuthorIdent().getName())
- .append(" <").append(commit.getAuthorIdent().getEmailAddress()) //$NON-NLS-1$
- .append(">\n"); //$NON-NLS-1$
- sb.append("Date").append(": ") //$NON-NLS-1$ //$NON-NLS-2$
- .append(dtfmt.format(commit.getAuthorIdent().getWhen()))
- .append("\n"); //$NON-NLS-1$
- sb.append("Subject").append(": [PATCH] ") //$NON-NLS-1$ //$NON-NLS-2$
- .append(commit.getShortMessage());
-
- String message = commit.getFullMessage().substring(
- commit.getShortMessage().length());
- sb.append(message).append("\n\n"); //$NON-NLS-1$
- }
-
private void copyToClipboard(final String content) {
getShell().getDisplay().syncExec(new Runnable() {
public void run() {
@@ -239,6 +169,18 @@ public class GitCreatePatchWizard extends Wizard {
});
}
+ private void writeToFile(final String fileName, String content)
+ throws IOException {
+ Writer output = new BufferedWriter(new FileWriter(fileName));
+ try {
+ // FileWriter always assumes default encoding is
+ // OK!
+ output.write(content);
+ } finally {
+ output.close();
+ }
+ }
+
/**
* A wizard page to choose the target location
*/
@@ -358,23 +300,9 @@ public class GitCreatePatchWizard extends Wizard {
}
private String createFileName() {
- String name = commit.getShortMessage();
-
- name = name.trim();
- try {
- name = URLEncoder.encode(name, "UTF-8"); //$NON-NLS-1$
- } catch (UnsupportedEncodingException e) {
- // We're pretty sure that UTF-8 will be supported in future
- }
- if (name.length() > 80)
- name = name.substring(0, 80);
- while (name.endsWith(".")) //$NON-NLS-1$
- name = name.substring(0, name.length() - 1);
- name = name.concat(".patch"); //$NON-NLS-1$
-
+ String suggestedFileName = CreatePatchOperation.suggestFileName(commit);
String defaultPath = db.getWorkTree().getAbsolutePath();
-
- return (new File(defaultPath, name)).getPath();
+ return (new File(defaultPath, suggestedFileName)).getPath();
}
/**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreatePatchHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreatePatchHandler.java
index ddd8eefcca..3df9d7d548 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreatePatchHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreatePatchHandler.java
@@ -15,8 +15,6 @@ import org.eclipse.egit.ui.internal.history.GitHistoryPage;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
/**
* Create a patch based on a commit.
@@ -28,10 +26,7 @@ public class CreatePatchHandler extends AbstractHistoryCommandHandler {
if (selection.size() == 1) {
RevCommit commit = (RevCommit) selection.getFirstElement();
Repository repo = getRepository(event);
- TreeWalk fileWalker = new TreeWalk(repo);
- fileWalker.setRecursive(true);
- fileWalker.setFilter(TreeFilter.ANY_DIFF);
- GitCreatePatchWizard.run(getPart(event), commit, fileWalker, repo);
+ GitCreatePatchWizard.run(getPart(event), commit, repo);
}
return null;
}

Back to the top