diff options
author | Tomasz Zarna | 2011-12-31 00:33:50 +0000 |
---|---|---|
committer | Matthias Sohn | 2011-12-31 00:33:50 +0000 |
commit | 3656b0aaf82c0aea5599fc957927c91e7cfe2602 (patch) | |
tree | 8d5df0667b686038f316630f1fa246176ddde24e | |
parent | 4632b349588c8326f4c2532c40831cc46c1d6594 (diff) | |
download | egit-3656b0aaf82c0aea5599fc957927c91e7cfe2602.tar.gz egit-3656b0aaf82c0aea5599fc957927c91e7cfe2602.tar.xz egit-3656b0aaf82c0aea5599fc957927c91e7cfe2602.zip |
Team > Create patch is missing
The change adds the missing action. The action opens the Create Patch
wizard allowing to save changes from your working tree in a file or
clipboard. It makes the second param for CreatePatchOperation i.e.
commit optional.
Bug: 341036
Change-Id: Ib32830d732d31c1057ed7c969399f21223908b06
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
14 files changed, 241 insertions, 40 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 index 4a56181900..fb5941344b 100644 --- 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 @@ -114,7 +114,7 @@ public class CreatePatchOperationTest extends GitTestCase { operation.execute(null); } - @Test(expected = IllegalArgumentException.class) + @Test public void testNullCommit() throws Exception { new CreatePatchOperation(testRepository.getRepository(), null); } 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 a3666d5531..6a5165b6bf 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 @@ -213,10 +213,16 @@ public class CoreText extends NLS { public static String CreateLocalBranchOperation_CreatingBranchMessage; /** */ - public static String CreatePatchOperation_commitRequired; + public static String CreatePatchOperation_repoRequired; /** */ - public static String CreatePatchOperation_repoRequired; + public static String CreatePatchOperation_cannotCreatePatchForMergeCommit; + + /** */ + public static String CreatePatchOperation_cannotCreatePatchForFirstCommit; + + /** */ + public static String CreatePatchOperation_patchFileCouldNotBeWritten; /** */ public static String IndexDiffCacheEntry_reindexing; 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 6dc1c22e30..7599c69251 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 @@ -89,8 +89,10 @@ 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 +CreatePatchOperation_cannotCreatePatchForMergeCommit=Cannot create patch for merge commit +CreatePatchOperation_cannotCreatePatchForFirstCommit=Cannot create patch for first commit +CreatePatchOperation_patchFileCouldNotBeWritten=Patch file could not be written IndexDiffCacheEntry_reindexing=Re-indexing repository {0} 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/op/CreatePatchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java index 80b0984cd1..5c10280edb 100644 --- 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 @@ -28,10 +28,12 @@ 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.diff.DiffFormatter; +import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.treewalk.FileTreeIterator; /** * Creates a patch for a specific commit @@ -66,9 +68,6 @@ public class CreatePatchOperation implements IEGitOperation { if (repository == null) throw new IllegalArgumentException( CoreText.CreatePatchOperation_repoRequired); - if (commit == null) - throw new IllegalArgumentException( - CoreText.CreatePatchOperation_commitRequired); this.repository = repository; this.commit = commit; } @@ -102,32 +101,38 @@ public class CreatePatchOperation implements IEGitOperation { diffFmt.setProgressMonitor(gitMonitor); diffFmt.setContext(contextLines); - 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); + diffFmt.setRepository(repository); + 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); + if (commit != null) { + RevCommit[] parents = commit.getParents(); + if (parents.length > 1) + throw new IllegalStateException( + CoreText.CreatePatchOperation_cannotCreatePatchForMergeCommit); + if (parents.length == 0) + throw new IllegalStateException( + CoreText.CreatePatchOperation_cannotCreatePatchForFirstCommit); + + 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); + } + } else { + diffFmt.format( + new DirCacheIterator(repository.readDirCache()), + new FileTreeIterator(repository)); } } catch (IOException e) { - Activator.logError("Patch file could not be written", e); //$NON-NLS-1$ + Activator.logError(CoreText.CreatePatchOperation_patchFileCouldNotBeWritten, e); } patchContent = sb.toString(); diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties index 1d1bb9ebae..0b2a1a368d 100644 --- a/org.eclipse.egit.ui/plugin.properties +++ b/org.eclipse.egit.ui/plugin.properties @@ -260,6 +260,8 @@ FetchFromUpstreamAction.label = &Fetch from Upstream CompareWithBranchOrTagAction.label = &Branch, Tag, or Reference... MergeToolAction.label = Merge Tool CompareWithCommitAction.label = Commit... +CreatePatchAction.label = Create Patch... +CreatePatchAction.tooltip = Compare your working tree contents with the index and generate a diff file that can be used as a patch file. TreeCompareView.name = Git Tree Compare TeamMenu.label = T&eam RebaseCommand.label = Rebase diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml index d56a9861c0..a23172ed38 100644 --- a/org.eclipse.egit.ui/plugin.xml +++ b/org.eclipse.egit.ui/plugin.xml @@ -213,8 +213,16 @@ label="%CompareWithCommitAction.label" menubarPath="compareWithMenu/gitCompareWithGroup"> </action> - </objectContribution> - <objectContribution + <action + class="org.eclipse.egit.ui.internal.actions.CreatePatchAction" + enablesFor="1" + id="org.eclipse.egit.ui.internal.actions.CreatePatchAction" + label="%CreatePatchAction.label" + menubarPath="team.main/group6" + tooltip="%CreatePatchAction.tooltip"> + </action> + </objectContribution> + <objectContribution adaptable="true" id="org.eclipse.egit.ui.fileContributions" objectClass="org.eclipse.core.resources.IFile"> diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java index 496737537c..97a2932ad8 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIText.java @@ -2923,6 +2923,12 @@ public class UIText extends NLS { public static String GitCreateGeneralProjectPage_ProjectNameLabel; /** */ + public static String GitCreatePatchAction_cannotCreatePatch; + + /** */ + public static String GitCreatePatchAction_workingTreeClean; + + /** */ public static String GitCreatePatchWizard_Browse; /** */ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java index bdee194cdf..1a8e4d11a5 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ActionCommands.java @@ -23,6 +23,9 @@ public class ActionCommands { /** "Apply patch" action command id */ public static final String APPLY_PATCH = "org.eclipse.egit.ui.team.ApplyPatch"; //$NON-NLS-1$ + /** "Create patch" action command id */ + public static final String CREATE_PATCH = "org.eclipse.egit.ui.team.CreatePatch"; //$NON-NLS-1$ + /** "Branch" action command id */ public static final String BRANCH_ACTION = "org.eclipse.egit.ui.team.Branch"; //$NON-NLS-1$ diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreatePatchAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreatePatchAction.java new file mode 100644 index 0000000000..2b214b7245 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreatePatchAction.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (C) 2011, Tomasz Zarna <Tomasz.Zarna@pl.ibm.com> + * + * 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 + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +/** + * Action to generate a patch file using the diff command. + */ +public class CreatePatchAction extends RepositoryAction { + + /** + * + */ + public CreatePatchAction() { + super(ActionCommands.CREATE_PATCH, new CreatePatchActionHandler()); + } +}
\ No newline at end of file diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreatePatchActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreatePatchActionHandler.java new file mode 100644 index 0000000000..dcee905b62 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CreatePatchActionHandler.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (C) 2011, Tomasz Zarna <Tomasz.Zarna@pl.ibm.com> + * + * 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 + *******************************************************************************/ +package org.eclipse.egit.ui.internal.actions; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.egit.ui.internal.patch.PatchOperationUI; + +/** + * The "Create Patch" action. + */ +public class CreatePatchActionHandler extends RepositoryActionHandler { + + public Object execute(ExecutionEvent event) throws ExecutionException { + PatchOperationUI.createPatch(getPart(event), getRepository()).start(); + return null; + } + + @Override + public boolean isEnabled() { + return getRepository() != null; + } +} 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 0dffea9554..e37eb919c9 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 @@ -53,8 +53,8 @@ import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IWorkbenchPart; /** * A wizard for creating a patch file by running the git diff command. @@ -76,17 +76,16 @@ public class GitCreatePatchWizard extends Wizard { /** * - * @param part + * @param shell * @param commit * @param db */ - public static void run(IWorkbenchPart part, final RevCommit commit, + public static void run(Shell shell, final RevCommit commit, Repository db) { final String title = UIText.GitCreatePatchWizard_CreatePatchTitle; final GitCreatePatchWizard wizard = new GitCreatePatchWizard(commit, db); wizard.setWindowTitle(title); - WizardDialog dialog = new WizardDialog(part.getSite().getShell(), - wizard); + WizardDialog dialog = new WizardDialog(shell, wizard); dialog.setMinimumPageSize(INITIAL_WIDTH, INITIAL_HEIGHT); dialog.setHelpAvailable(false); dialog.open(); @@ -326,7 +325,9 @@ public class GitCreatePatchWizard extends Wizard { } private String createFileName() { - String suggestedFileName = CreatePatchOperation.suggestFileName(commit); + String suggestedFileName = commit != null ? CreatePatchOperation + .suggestFileName(commit) : db.getWorkTree().getName() + .concat(".patch"); //$NON-NLS-1$ String path = getDialogSettings().get(PATH_KEY); if (path != null) return Path.fromPortableString(path).append(suggestedFileName).toOSString(); @@ -402,7 +403,7 @@ public class GitCreatePatchWizard extends Wizard { * * A wizard Page used to specify options of the created patch */ - public static class OptionsPage extends WizardPage { + public class OptionsPage extends WizardPage { private Button gitFormat; private Text contextLines; private Label contextLinesLabel; @@ -429,6 +430,7 @@ public class GitCreatePatchWizard extends Wizard { gitFormat = new Button(composite, SWT.CHECK); gitFormat.setText(UIText.GitCreatePatchWizard_GitFormat); gitFormat.setLayoutData(gd); + gitFormat.setEnabled(commit != null); contextLinesLabel = new Label(composite, SWT.NONE); contextLinesLabel.setText(UIText.GitCreatePatchWizard_LinesOfContext); 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 3df9d7d548..0ded6401ce 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 @@ -10,8 +10,8 @@ package org.eclipse.egit.ui.internal.history.command; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; -import org.eclipse.egit.ui.internal.history.GitCreatePatchWizard; import org.eclipse.egit.ui.internal.history.GitHistoryPage; +import org.eclipse.egit.ui.internal.patch.PatchOperationUI; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; @@ -25,8 +25,8 @@ public class CreatePatchHandler extends AbstractHistoryCommandHandler { IStructuredSelection selection = getSelection(getPage()); if (selection.size() == 1) { RevCommit commit = (RevCommit) selection.getFirstElement(); - Repository repo = getRepository(event); - GitCreatePatchWizard.run(getPart(event), commit, repo); + Repository repo = getRepository(event); + PatchOperationUI.createPatch(getPart(event), commit, repo).start(); } return null; } diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/patch/PatchOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/patch/PatchOperationUI.java new file mode 100644 index 0000000000..cda897b713 --- /dev/null +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/patch/PatchOperationUI.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (C) 2011, Tomasz Zarna <Tomasz.Zarna@pl.ibm.com> + * + * 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 + *******************************************************************************/ +package org.eclipse.egit.ui.internal.patch; + +import org.eclipse.egit.core.op.CreatePatchOperation; +import org.eclipse.egit.ui.UIText; +import org.eclipse.egit.ui.internal.history.GitCreatePatchWizard; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.Status; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; + +/** + * The UI wrapper for {@link CreatePatchOperation} + */ +public class PatchOperationUI { + private IWorkbenchPart part; + + private Repository repository; + + private RevCommit commit; + + private PatchOperationUI(IWorkbenchPart part, Repository repo) { + this.part = part; + this.repository = repo; + } + + private PatchOperationUI(IWorkbenchPart part, Repository repo, + RevCommit commit) { + this(part, repo); + this.commit = commit; + } + + /** + * Create an operation for creating a patch for a specific commit. + * + * @param part + * the part + * @param commit + * a commit + * @param repo + * the repository + * @return the {@link PatchOperationUI} + */ + public static PatchOperationUI createPatch(IWorkbenchPart part, + RevCommit commit, Repository repo) { + return new PatchOperationUI(part, repo, commit); + } + + /** + * Create an operation for creating a patch for change made relative to the + * index. + * + * @param part + * the part + * @param repo + * the repository + * @return the {@link PatchOperationUI} + */ + public static PatchOperationUI createPatch(IWorkbenchPart part, + Repository repo) { + return new PatchOperationUI(null, repo); + } + + /** + * Starts the operation asynchronously + */ + public void start() { + if (commit != null) { + GitCreatePatchWizard.run(getShell(), commit, repository); + return; + } else + + if (isWorkingTreeClean()) { + MessageDialog.openInformation(getShell(), + UIText.GitCreatePatchAction_cannotCreatePatch, + UIText.GitCreatePatchAction_workingTreeClean); + return; + } + GitCreatePatchWizard.run(getShell(), null, repository); + } + + private boolean isWorkingTreeClean() { + Git git = new Git(repository); + try { + Status status = git.status().call(); + return status.getModified().isEmpty() + && status.getUntracked().isEmpty() + && status.getMissing().isEmpty(); + } catch (Exception e) { + MessageDialog.openError(getShell(), + UIText.GitCreatePatchAction_cannotCreatePatch, e + .getMessage() == null ? e.getMessage() + : UIText.GitCreatePatchWizard_InternalError); + } + return true; + } + + private Shell getShell() { + if (part != null) + return part.getSite().getShell(); + return PlatformUI.getWorkbench().getDisplay().getActiveShell(); + } +} diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties index d30c82ad76..c40d974034 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties @@ -1012,6 +1012,8 @@ GitCreateGeneralProjectPage_FileExistsInDirMessage=A {0} file already exists in GitCreateGeneralProjectPage_FileNotDirMessage=File {0} is not a directory GitCreateGeneralProjectPage_PorjectAlreadyExistsMessage=Project {0} already exists GitCreateGeneralProjectPage_ProjectNameLabel=Project name +GitCreatePatchAction_cannotCreatePatch=Cannot create patch +GitCreatePatchAction_workingTreeClean=There are no changes in working tree GitCreatePatchWizard_Browse=B&rowse... GitCreatePatchWizard_Clipboard=&Clipboard GitCreatePatchWizard_ContextMustBePositiveInt=Context must be a valid number of lines ( >= 0 ) |