diff options
author | Matthias Sohn | 2015-06-01 22:19:36 +0000 |
---|---|---|
committer | Matthias Sohn | 2015-06-01 22:19:44 +0000 |
commit | 696ffd3233fead9fd538136b658bcb5d62cecac4 (patch) | |
tree | ea57e4984b0718ceef3eb6241d26a5abeceeace2 | |
parent | 52dbed6eaf96bb2a9e4999259b96745959ff55f9 (diff) | |
parent | 80c94b153af22f28dadec852fb2aa2a3bbd76f66 (diff) | |
download | egit-696ffd3233fead9fd538136b658bcb5d62cecac4.tar.gz egit-696ffd3233fead9fd538136b658bcb5d62cecac4.tar.xz egit-696ffd3233fead9fd538136b658bcb5d62cecac4.zip |
Merge branch 'master' into stable-4.0
* master:
Update 4.5 target platform to use final Mars Orbit repository
[gitflow] track feature will always claim no remote features exist
[gitflow] explicitly notify the user about merge/rebase conflicts
Avoid deadlocks during resource changes in AutoShareProjects
[gitflow] Fix broken "start release" from commit
Change-Id: I8c1b27babee7323d75694a080307cd1260a62258
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
25 files changed, 581 insertions, 122 deletions
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/Activator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/Activator.java index 6bff4ab07e..b44bb3aed0 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/Activator.java +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/Activator.java @@ -27,11 +27,13 @@ import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.preferences.DefaultScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.InstanceScope; @@ -280,14 +282,15 @@ public class Activator extends Plugin implements DebugOptionsListener { shareGitProjectsJob, IResourceChangeEvent.POST_CHANGE); } - private static class AutoShareProjects implements - IResourceChangeListener { + private static class AutoShareProjects implements IResourceChangeListener { private static int INTERESTING_CHANGES = IResourceDelta.ADDED | IResourceDelta.OPEN; + private final CheckProjectsToShare checkProjectsJob; + public AutoShareProjects() { - // empty + checkProjectsJob = new CheckProjectsToShare(); } private boolean doAutoShare() { @@ -301,75 +304,149 @@ public class Activator extends Plugin implements DebugOptionsListener { } public void resourceChanged(IResourceChangeEvent event) { + if (!doAutoShare()) { + return; + } try { - - final Map<IProject, File> projects = new HashMap<IProject, File>(); - + final Set<IProject> projectCandidates = new LinkedHashSet<>(); event.getDelta().accept(new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta) throws CoreException { - return visitConnect(delta, projects); + return collectOpenedProjects(delta, + projectCandidates); } }); - - if (projects.size() > 0) { - ConnectProviderOperation op = new ConnectProviderOperation( - projects); - JobUtil.scheduleUserJob(op, - CoreText.Activator_AutoShareJobName, - JobFamilies.AUTO_SHARE); + if(!projectCandidates.isEmpty()){ + checkProjectsJob.addProjectsToCheck(projectCandidates); } - } catch (CoreException e) { Activator.logError(e.getMessage(), e); return; } } - private boolean visitConnect(IResourceDelta delta, - final Map<IProject, File> projects) throws CoreException { - if (!doAutoShare()) - return false; + /* + * This method should not use RepositoryMapping.getMapping(project) or + * RepositoryProvider.getProvider(project) which can trigger + * RepositoryProvider.map(project) and deadlock current thread. See + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=468270 + */ + private boolean collectOpenedProjects(IResourceDelta delta, + Set<IProject> projects) { if (delta.getKind() == IResourceDelta.CHANGED - && (delta.getFlags() & INTERESTING_CHANGES) == 0) + && (delta.getFlags() & INTERESTING_CHANGES) == 0) { return true; + } final IResource resource = delta.getResource(); - if (!resource.exists() || !resource.isAccessible() || - resource.isLinked(IResource.CHECK_ANCESTORS)) - return false; - if (resource.getType() != IResource.PROJECT) + if (resource.getType() == IResource.ROOT) { return true; - if (RepositoryMapping.getMapping(resource) != null) + } + if (resource.getType() != IResource.PROJECT) { + return false; + } + if (!resource.isAccessible()) { return false; - final IProject project = (IProject) resource; + } + projects.add((IProject) resource); + return false; + } + + } + + private static class CheckProjectsToShare extends Job { + private Object lock = new Object(); + + private Set<IProject> projectCandidates; + + public CheckProjectsToShare() { + super(CoreText.Activator_AutoShareJobName); + this.projectCandidates = new LinkedHashSet<IProject>(); + setUser(false); + setSystem(true); + } + + public void addProjectsToCheck(Set<IProject> projects) { + synchronized (lock) { + this.projectCandidates.addAll(projects); + if (!projectCandidates.isEmpty()) { + schedule(100); + } + } + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + Set<IProject> projectsToCheck; + synchronized (lock) { + projectsToCheck = projectCandidates; + projectCandidates = new LinkedHashSet<>(); + } + if (projectsToCheck.isEmpty()) { + return Status.OK_STATUS; + } + + final Map<IProject, File> projects = new HashMap<IProject, File>(); + for (IProject project : projectsToCheck) { + if (project.isAccessible()) { + try { + visitConnect(project, projects); + } catch (CoreException e) { + logError(e.getMessage(), e); + } + } + } + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + if (projects.size() > 0) { + ConnectProviderOperation op = new ConnectProviderOperation( + projects); + JobUtil.scheduleUserJob(op, + CoreText.Activator_AutoShareJobName, + JobFamilies.AUTO_SHARE); + } + return Status.OK_STATUS; + } + + private void visitConnect(IProject project, + final Map<IProject, File> projects) throws CoreException { + + if (RepositoryMapping.getMapping(project) != null) { + return; + } RepositoryProvider provider = RepositoryProvider .getProvider(project); // respect if project is already shared with another // team provider - if (provider != null) - return false; + if (provider != null) { + return; + } RepositoryFinder f = new RepositoryFinder(project); f.setFindInChildren(false); Collection<RepositoryMapping> mappings = f.find(new NullProgressMonitor()); - if (mappings.size() != 1) - return false; + if (mappings.size() != 1) { + return; + } RepositoryMapping m = mappings.iterator().next(); IPath gitDirPath = m.getGitDirAbsolutePath(); - if (gitDirPath.segmentCount() == 0) - return false; + if (gitDirPath.segmentCount() == 0) { + return; + } IPath workingDir = gitDirPath.removeLastSegments(1); // Don't connect "/" or "C:\" - if (workingDir.isRoot()) - return false; + if (workingDir.isRoot()) { + return; + } File userHome = FS.DETECTED.userHome(); if (userHome != null) { Path userHomePath = new Path(userHome.getAbsolutePath()); // Don't connect "/home" or "/home/username" - if (workingDir.isPrefixOf(userHomePath)) - return false; + if (workingDir.isPrefixOf(userHomePath)) { + return; + } } // connect @@ -382,7 +459,6 @@ public class Activator extends Plugin implements DebugOptionsListener { } catch (IllegalArgumentException e) { logError(CoreText.Activator_AutoSharingFailed, e); } - return false; } } diff --git a/org.eclipse.egit.gitflow.test/src/org/eclipse/egit/gitflow/op/HotfixFinishOperationTest.java b/org.eclipse.egit.gitflow.test/src/org/eclipse/egit/gitflow/op/HotfixFinishOperationTest.java index f7121845f8..899c4139b9 100644 --- a/org.eclipse.egit.gitflow.test/src/org/eclipse/egit/gitflow/op/HotfixFinishOperationTest.java +++ b/org.eclipse.egit.gitflow.test/src/org/eclipse/egit/gitflow/op/HotfixFinishOperationTest.java @@ -102,7 +102,7 @@ public class HotfixFinishOperationTest extends AbstractGitFlowOperationTest { RevCommit developHead = gfRepo.findHead(DEVELOP); assertEquals(developCommit, developHead); assertEquals(MergeResult.MergeStatus.CONFLICTING, hotfixFinishOperation - .getOperationResult().getMergeStatus()); + .getMergeResult().getMergeStatus()); // merged on master RevCommit masterHead = gfRepo.findHead(MY_MASTER); diff --git a/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF index 02b66ec5e4..68fb89ca30 100644 --- a/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.egit.gitflow.ui/META-INF/MANIFEST.MF @@ -18,11 +18,13 @@ Import-Package: org.eclipse.egit.core;version="[4.0.0,4.1.0)", org.eclipse.egit.ui;version="[4.0.0,4.1.0)", org.eclipse.egit.ui.internal;version="[4.0.0,4.1.0)", org.eclipse.egit.ui.internal.branch;version="[4.0.0,4.1.0)", + org.eclipse.egit.ui.internal.history;version="[4.0.0,4.1.0)", org.eclipse.egit.ui.internal.repository.tree;version="[4.0.0,4.1.0)", org.eclipse.egit.ui.internal.selection;version="[4.0.0,4.1.0)", org.eclipse.jgit.api;version="[4.0.0,4.1.0)", org.eclipse.jgit.api.errors;version="[4.0.0,4.1.0)", org.eclipse.jgit.lib;version="[4.0.0,4.1.0)", + org.eclipse.jgit.merge;version="[4.0.0,4.1.0)", org.eclipse.jgit.revplot;version="[4.0.0,4.1.0)", org.eclipse.jgit.revwalk;version="[4.0.0,4.1.0)" Require-Bundle: org.eclipse.core.jobs;bundle-version="[3.4.0,4.0.0)", diff --git a/org.eclipse.egit.gitflow.ui/plugin.xml b/org.eclipse.egit.gitflow.ui/plugin.xml index e78a9159c3..4987603aed 100644 --- a/org.eclipse.egit.gitflow.ui/plugin.xml +++ b/org.eclipse.egit.gitflow.ui/plugin.xml @@ -127,18 +127,6 @@ </command> </menu> </menuContribution> - <menuContribution - allPopups="false" - locationURI="popup:org.eclipse.egit.ui.historyPageContributions?after=additions"> - <menu - label="%TeamGitFlowMenu.name"> - <command - commandId="org.eclipse.egit.gitflow.ui.command.releaseStart" - label="%TeamGitFlowReleaseStart.name" - style="push"> - </command> - </menu> - </menuContribution> </extension> <extension point="org.eclipse.ui.commands"> @@ -615,6 +603,13 @@ <adapter type="org.eclipse.jgit.lib.Repository"/> </factory> </extension> + <extension + point="org.eclipse.core.runtime.adapters"> + <factory adaptableType="org.eclipse.team.ui.history.IHistoryView" + class="org.eclipse.egit.gitflow.ui.internal.factories.GitFlowAdapterFactory"> + <adapter type="org.eclipse.jgit.lib.Repository"/> + </factory> + </extension> <extension @@ -740,4 +735,18 @@ </command> </menuContribution> </extension> + <extension + point="org.eclipse.ui.menus"> + <menuContribution + allPopups="false" + locationURI="popup:org.eclipse.egit.ui.historyPageContributions?after=additions"> + <menu + label="%TeamGitFlowMenu.name"> + <dynamic + class="org.eclipse.egit.gitflow.ui.internal.menu.DynamicHistoryMenu" + id="org.eclipse.egit.gitflow.menu.history"> + </dynamic> + </menu> + </menuContribution> + </extension> </plugin> diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/UIText.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/UIText.java index a43b81d763..ac3ecd76fa 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/UIText.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/UIText.java @@ -28,6 +28,18 @@ public class UIText extends NLS { } /** */ + public static String DynamicHistoryMenu_startGitflowReleaseFrom; + + /** */ + public static String FeatureFinishHandler_Conflicts; + + /** */ + public static String FeatureFinishHandler_conflictsWhileMergingFromTo; + + /** */ + public static String FeatureFinishHandler_featureFinishConflicts; + + /** */ public static String FeatureFinishHandler_finishingFeature; /** */ @@ -70,9 +82,15 @@ public class UIText extends NLS { public static String FeatureTrackHandler_trackingFeature; /** */ + public static String HotfixFinishHandler_Conflicts; + + /** */ public static String HotfixFinishHandler_finishingHotfix; /** */ + public static String HotfixFinishHandler_hotfixFinishConflicts; + + /** */ public static String HotfixStartHandler_pleaseProvideANameForTheNewHotfix; /** */ @@ -85,9 +103,15 @@ public class UIText extends NLS { public static String InitHandler_initializing; /** */ + public static String ReleaseFinishHandler_Conflicts; + + /** */ public static String ReleaseFinishHandler_finishingRelease; /** */ + public static String ReleaseFinishHandler_releaseFinishConflicts; + + /** */ public static String ReleaseStartHandler_provideANameForTheNewRelease; /** */ @@ -125,4 +149,10 @@ public class UIText extends NLS { /** */ public static String FeatureCheckoutHandler_cleanupDialog_text; + + /** */ + public static String HotfixFinishOperation_unexpectedConflictsHotfixAborted; + + /** */ + public static String ReleaseFinishOperation_unexpectedConflictsReleaseAborted; } diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/AbstractFinishHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/AbstractFinishHandler.java new file mode 100644 index 0000000000..f592eff8d4 --- /dev/null +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/AbstractFinishHandler.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (C) 2015, Max Hohenegger <eclipse@hohenegger.eu> + * + * 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.gitflow.ui.internal.actions; + +import java.util.Set; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.egit.gitflow.ui.Activator; +import org.eclipse.egit.gitflow.ui.internal.UIText; +import org.eclipse.jgit.api.MergeResult; +import org.eclipse.osgi.util.NLS; + +/** + * Contains shared code for handling finish operations + */ +public abstract class AbstractFinishHandler extends AbstractHandler { + /** + * @param develop + * @param featureBranch + * @param mergeResult + * @return Status containing detailed information about what went wrong + * during merge or rebase + */ + protected MultiStatus createConflictWarning(String develop, + String featureBranch, MergeResult mergeResult) { + String pluginId = Activator.getPluginId(); + MultiStatus info = new MultiStatus(pluginId, 1, + UIText.FeatureFinishHandler_featureFinishConflicts, null); + info.add(new Status(IStatus.WARNING, pluginId, 1, NLS.bind( + UIText.FeatureFinishHandler_conflictsWhileMergingFromTo, + featureBranch, develop), null)); + + Set<String> paths = mergeResult.getConflicts().keySet(); + for (String path : paths) { + info.add(new Status(IStatus.WARNING, pluginId, 1, path, null)); + } + + return info; + } +} diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureCheckoutHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureCheckoutHandler.java index d237fc1501..93a93f708c 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureCheckoutHandler.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureCheckoutHandler.java @@ -8,6 +8,8 @@ *******************************************************************************/ package org.eclipse.egit.gitflow.ui.internal.actions; +import static org.eclipse.egit.gitflow.ui.Activator.error; +import static org.eclipse.egit.gitflow.ui.internal.JobFamilies.GITFLOW_FAMILY; import static org.eclipse.jgit.lib.Constants.R_HEADS; import java.text.MessageFormat; @@ -18,7 +20,10 @@ import java.util.List; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.egit.core.internal.job.JobUtil; import org.eclipse.egit.gitflow.GitFlowRepository; import org.eclipse.egit.gitflow.op.FeatureCheckoutOperation; @@ -69,6 +74,13 @@ public class FeatureCheckoutHandler extends AbstractHandler { JobUtil.scheduleUserWorkspaceJob(checkoutOperation, UIText.FeatureCheckoutHandler_checkingOutFeature, JobFamilies.GITFLOW_FAMILY); + IJobManager jobMan = Job.getJobManager(); + try { + jobMan.join(GITFLOW_FAMILY, null); + } catch (OperationCanceledException | InterruptedException e) { + return error(e.getMessage(), e); + } + CheckoutResult result = checkoutOperation.getResult(); if (!CheckoutResult.Status.OK.equals(result.getStatus())) { Shell shell = HandlerUtil.getActiveShell(event); diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureFinishHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureFinishHandler.java index 69fcc8b2a6..1dd5744b6a 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureFinishHandler.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureFinishHandler.java @@ -12,31 +12,49 @@ import static org.eclipse.egit.gitflow.ui.Activator.error; import java.io.IOException; -import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.egit.core.internal.job.JobUtil; import org.eclipse.egit.gitflow.GitFlowRepository; import org.eclipse.egit.gitflow.WrongGitFlowStateException; import org.eclipse.egit.gitflow.op.FeatureFinishOperation; import org.eclipse.egit.gitflow.ui.internal.JobFamilies; import org.eclipse.egit.gitflow.ui.internal.UIText; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jgit.api.MergeResult; +import org.eclipse.jgit.api.MergeResult.MergeStatus; /** * git flow feature finish */ -public class FeatureFinishHandler extends AbstractHandler { +public class FeatureFinishHandler extends AbstractFinishHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { final GitFlowRepository gfRepo = GitFlowHandlerUtil.getRepository(event); - try { FeatureFinishOperation operation = new FeatureFinishOperation(gfRepo); + String featureBranch = gfRepo.getRepository().getBranch(); + String develop = gfRepo.getConfig().getDevelop(); + JobUtil.scheduleUserWorkspaceJob(operation, UIText.FeatureFinishHandler_finishingFeature, JobFamilies.GITFLOW_FAMILY); - } catch (WrongGitFlowStateException | CoreException | IOException e) { + IJobManager jobMan = Job.getJobManager(); + jobMan.join(JobFamilies.GITFLOW_FAMILY, null); + + MergeResult mergeResult = operation.getMergeResult(); + MergeStatus mergeStatus = mergeResult.getMergeStatus(); + if (MergeStatus.CONFLICTING.equals(mergeStatus)) { + MultiStatus warning = createConflictWarning(develop, featureBranch, mergeResult); + ErrorDialog.openError(null, UIText.FeatureFinishHandler_Conflicts, null, warning); + } + } catch (WrongGitFlowStateException | CoreException | IOException + | OperationCanceledException | InterruptedException e) { return error(e.getMessage(), e); } diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureRebaseHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureRebaseHandler.java index d21127a3cb..2c26f16ba0 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureRebaseHandler.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureRebaseHandler.java @@ -9,10 +9,14 @@ package org.eclipse.egit.gitflow.ui.internal.actions; import static org.eclipse.egit.gitflow.ui.Activator.error; +import static org.eclipse.egit.gitflow.ui.internal.JobFamilies.GITFLOW_FAMILY; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.egit.core.internal.job.JobUtil; import org.eclipse.egit.gitflow.GitFlowRepository; import org.eclipse.egit.gitflow.op.FeatureRebaseOperation; @@ -22,7 +26,6 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jgit.api.RebaseResult; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.handlers.HandlerUtil; /** * git flow feature rebase @@ -38,16 +41,22 @@ public class FeatureRebaseHandler extends AbstractHandler { JobUtil.scheduleUserWorkspaceJob(featureRebaseOperation, UIText.FeatureRebaseHandler_rebasingFeature, JobFamilies.GITFLOW_FAMILY); + IJobManager jobMan = Job.getJobManager(); + try { + jobMan.join(GITFLOW_FAMILY, null); + } catch (OperationCanceledException | InterruptedException e) { + return error(e.getMessage(), e); + } RebaseResult.Status status = featureRebaseOperation .getOperationResult().getStatus(); if (RebaseResult.Status.FAILED.equals(status)) { return error(UIText.FeatureRebaseHandler_rebaseFailed); } - if (!RebaseResult.Status.CONFLICTS.equals(status)) { + if (!RebaseResult.Status.STOPPED.equals(status)) { return null; } - MessageDialog.openInformation(HandlerUtil.getActiveShell(event), + MessageDialog.openWarning(null, UIText.FeatureRebaseHandler_conflicts, UIText.FeatureRebaseHandler_resolveConflictsManually); try { diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureTrackHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureTrackHandler.java index 80f7148095..750cfbeb06 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureTrackHandler.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/FeatureTrackHandler.java @@ -18,13 +18,19 @@ import java.util.List; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.egit.core.internal.job.JobUtil; import org.eclipse.egit.gitflow.GitFlowRepository; import org.eclipse.egit.gitflow.op.FeatureListOperation; import org.eclipse.egit.gitflow.op.FeatureTrackOperation; + +import static org.eclipse.egit.gitflow.ui.Activator.error; + import org.eclipse.egit.gitflow.ui.Activator; -import org.eclipse.egit.gitflow.ui.internal.JobFamilies; +import static org.eclipse.egit.gitflow.ui.internal.JobFamilies.GITFLOW_FAMILY; import org.eclipse.egit.gitflow.ui.internal.UIText; import org.eclipse.egit.gitflow.ui.internal.dialog.AbstractGitFlowBranchSelectionDialog; import org.eclipse.egit.ui.UIPreferences; @@ -49,7 +55,15 @@ public class FeatureTrackHandler extends AbstractHandler { FeatureListOperation featureListOperation = new FeatureListOperation( gfRepo, timeout); JobUtil.scheduleUserWorkspaceJob(featureListOperation, - UIText.FeatureTrackHandler_fetchingRemoteFeatures, JobFamilies.GITFLOW_FAMILY); + UIText.FeatureTrackHandler_fetchingRemoteFeatures, + GITFLOW_FAMILY); + IJobManager jobMan = Job.getJobManager(); + try { + jobMan.join(GITFLOW_FAMILY, null); + } catch (OperationCanceledException | InterruptedException e) { + return error(e.getMessage(), e); + } + List<Ref> remoteFeatures = featureListOperation.getResult(); if (remoteFeatures.isEmpty()) { MessageDialog.openInformation(activeShell, UIText.FeatureTrackHandler_noRemoteFeatures, @@ -75,7 +89,7 @@ public class FeatureTrackHandler extends AbstractHandler { FeatureTrackOperation featureTrackOperation = new FeatureTrackOperation( gfRepo, ref); JobUtil.scheduleUserWorkspaceJob(featureTrackOperation, - UIText.FeatureTrackHandler_trackingFeature, JobFamilies.GITFLOW_FAMILY); + UIText.FeatureTrackHandler_trackingFeature, GITFLOW_FAMILY); return null; diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/HotfixFinishHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/HotfixFinishHandler.java index 487fb319fc..b7043bcfb5 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/HotfixFinishHandler.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/HotfixFinishHandler.java @@ -12,21 +12,29 @@ import static org.eclipse.egit.gitflow.ui.Activator.error; import java.io.IOException; -import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.egit.core.internal.job.JobUtil; import org.eclipse.egit.gitflow.GitFlowRepository; import org.eclipse.egit.gitflow.WrongGitFlowStateException; import org.eclipse.egit.gitflow.op.HotfixFinishOperation; import org.eclipse.egit.gitflow.ui.internal.JobFamilies; import org.eclipse.egit.gitflow.ui.internal.UIText; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jgit.api.MergeResult; +import org.eclipse.jgit.api.MergeResult.MergeStatus; +import org.eclipse.osgi.util.NLS; /** * git flow hotfix finish */ -public class HotfixFinishHandler extends AbstractHandler { +public class HotfixFinishHandler extends AbstractFinishHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { @@ -35,13 +43,42 @@ public class HotfixFinishHandler extends AbstractHandler { HotfixFinishOperation hotfixFinishOperation; try { hotfixFinishOperation = new HotfixFinishOperation(gfRepo); + String hotfixBranch = gfRepo.getRepository().getBranch(); + String develop = gfRepo.getConfig().getDevelop(); + JobUtil.scheduleUserWorkspaceJob(hotfixFinishOperation, UIText.HotfixFinishHandler_finishingHotfix, JobFamilies.GITFLOW_FAMILY); - } catch (WrongGitFlowStateException | CoreException | IOException e) { + IJobManager jobMan = Job.getJobManager(); + jobMan.join(JobFamilies.GITFLOW_FAMILY, null); + + MergeResult mergeResult = hotfixFinishOperation.getMergeResult(); + MergeStatus mergeStatus = mergeResult.getMergeStatus(); + if (!MergeStatus.CONFLICTING.equals(mergeStatus)) { + return null; + } + if (handleConflictsOnMaster(gfRepo)) { + return null; + } + MultiStatus warning = createConflictWarning(develop, hotfixBranch, mergeResult); + ErrorDialog.openError(null, UIText.HotfixFinishHandler_Conflicts, null, warning); + } catch (WrongGitFlowStateException | CoreException | IOException + | OperationCanceledException | InterruptedException e) { return error(e.getMessage(), e); } return null; } + + private boolean handleConflictsOnMaster(GitFlowRepository gfRepo) + throws IOException { + if (!gfRepo.isMaster()) { + return false; + } + String master = gfRepo.getConfig().getMaster(); + MessageDialog.openError(null, UIText.HotfixFinishHandler_Conflicts, + NLS.bind(UIText.HotfixFinishOperation_unexpectedConflictsHotfixAborted, + master)); + return true; + } } diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseFinishHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseFinishHandler.java index b24f9f9d14..a641e8d93e 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseFinishHandler.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseFinishHandler.java @@ -12,36 +12,73 @@ import static org.eclipse.egit.gitflow.ui.Activator.error; import java.io.IOException; -import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.egit.core.internal.job.JobUtil; import org.eclipse.egit.gitflow.GitFlowRepository; import org.eclipse.egit.gitflow.WrongGitFlowStateException; import org.eclipse.egit.gitflow.op.ReleaseFinishOperation; import org.eclipse.egit.gitflow.ui.internal.JobFamilies; import org.eclipse.egit.gitflow.ui.internal.UIText; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jgit.api.MergeResult; +import org.eclipse.jgit.api.MergeResult.MergeStatus; +import org.eclipse.osgi.util.NLS; /** * git flow release finish */ -public class ReleaseFinishHandler extends AbstractHandler { +public class ReleaseFinishHandler extends AbstractFinishHandler { @Override - public Object execute(ExecutionEvent event) throws ExecutionException { + public Object execute(final ExecutionEvent event) throws ExecutionException { final GitFlowRepository gfRepo = GitFlowHandlerUtil.getRepository(event); - ReleaseFinishOperation releaseFinishOperation; + final ReleaseFinishOperation releaseFinishOperation; try { releaseFinishOperation = new ReleaseFinishOperation(gfRepo); + String releaseBranch = gfRepo.getRepository().getBranch(); + String develop = gfRepo.getConfig().getDevelop(); + JobUtil.scheduleUserWorkspaceJob(releaseFinishOperation, UIText.ReleaseFinishHandler_finishingRelease, JobFamilies.GITFLOW_FAMILY); - } catch (WrongGitFlowStateException | CoreException | IOException e) { + IJobManager jobMan = Job.getJobManager(); + jobMan.join(JobFamilies.GITFLOW_FAMILY, null); + + MergeResult mergeResult = releaseFinishOperation.getMergeResult(); + MergeStatus mergeStatus = mergeResult.getMergeStatus(); + if (!MergeStatus.CONFLICTING.equals(mergeStatus)) { + return null; + } + if (handleConflictsOnMaster(gfRepo)) { + return null; + } + MultiStatus warning = createConflictWarning(develop, releaseBranch, mergeResult); + ErrorDialog.openError(null, UIText.ReleaseFinishHandler_Conflicts, null, warning); + } catch (WrongGitFlowStateException | CoreException | IOException + | OperationCanceledException | InterruptedException e) { return error(e.getMessage(), e); } return null; } + + private boolean handleConflictsOnMaster(GitFlowRepository gfRepo) + throws IOException { + if (!gfRepo.isMaster()) { + return false; + } + String master = gfRepo.getConfig().getMaster(); + MessageDialog.openError(null, UIText.ReleaseFinishHandler_Conflicts, + NLS.bind(UIText.ReleaseFinishOperation_unexpectedConflictsReleaseAborted, + master)); + return true; + } } diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseStartFromCommitHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseStartFromCommitHandler.java new file mode 100644 index 0000000000..6c9a29b523 --- /dev/null +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseStartFromCommitHandler.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (C) 2015, Max Hohenegger <eclipse@hohenegger.eu> + * + * 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.gitflow.ui.internal.actions; + +import org.eclipse.egit.gitflow.GitFlowRepository; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Shell; + +/** + * Wrapper for ReleaseStartHandler + */ +public final class ReleaseStartFromCommitHandler extends SelectionAdapter { + private ReleaseStartHandler releaseStartHandler; + private GitFlowRepository gfRepo; + private String startCommitSha1; + private Shell activeShell; + + /** + * @param activeShell + * @param startCommitSha1 + * @param gfRepo + * + */ + public ReleaseStartFromCommitHandler(GitFlowRepository gfRepo, String startCommitSha1, Shell activeShell) { + this.gfRepo = gfRepo; + this.startCommitSha1 = startCommitSha1; + this.activeShell = activeShell; + releaseStartHandler = new ReleaseStartHandler(); + } + + public void widgetSelected(SelectionEvent e) { + releaseStartHandler.doExecute(gfRepo, startCommitSha1, activeShell); + } +}
\ No newline at end of file diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseStartHandler.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseStartHandler.java index 7c48aee1bc..4e9d201f37 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseStartHandler.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/actions/ReleaseStartHandler.java @@ -26,6 +26,7 @@ import org.eclipse.jface.window.Window; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revplot.PlotCommit; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.swt.widgets.Shell; import org.eclipse.team.ui.history.IHistoryView; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.handlers.HandlerUtil; @@ -40,14 +41,23 @@ public class ReleaseStartHandler extends AbstractHandler { final GitFlowRepository gfRepo = GitFlowHandlerUtil.getRepository(event); final String startCommitSha1 = getStartCommit(event); + Shell activeShell = HandlerUtil.getActiveShell(event); + + doExecute(gfRepo, startCommitSha1, activeShell); + + return null; + } + + void doExecute(GitFlowRepository gfRepo, + final String startCommitSha1, Shell activeShell) { InputDialog inputDialog = new InputDialog( - HandlerUtil.getActiveShell(event), + activeShell, UIText.ReleaseStartHandler_provideReleaseName, UIText.ReleaseStartHandler_provideANameForTheNewRelease, "", //$NON-NLS-1$ new ReleaseNameValidator(gfRepo)); if (inputDialog.open() != Window.OK) { - return null; + return; } final String releaseName = inputDialog.getValue(); @@ -57,8 +67,6 @@ public class ReleaseStartHandler extends AbstractHandler { JobUtil.scheduleUserWorkspaceJob(releaseStartOperation, UIText.ReleaseStartHandler_startingNewRelease, JobFamilies.GITFLOW_FAMILY); - - return null; } private String getStartCommit(ExecutionEvent event) diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/factories/GitFlowAdapterFactory.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/factories/GitFlowAdapterFactory.java index 1609d64e34..cbdd1f0110 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/factories/GitFlowAdapterFactory.java +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/factories/GitFlowAdapterFactory.java @@ -10,28 +10,32 @@ package org.eclipse.egit.gitflow.ui.internal.factories; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdapterFactory; -import org.eclipse.core.runtime.PlatformObject; -import org.eclipse.egit.core.internal.Utils; -import org.eclipse.egit.core.project.RepositoryMapping; -import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode; +import static org.eclipse.egit.core.project.RepositoryMapping.getMapping; +import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode; import org.eclipse.jgit.lib.Repository; +import org.eclipse.team.ui.history.IHistoryPage; +import org.eclipse.team.ui.history.IHistoryView; /** * Get JGit repository for element selected in Git Flow UI. */ public class GitFlowAdapterFactory implements IAdapterFactory { - @SuppressWarnings("unchecked") @Override - public Object getAdapter(Object adaptableObject, Class adapterType) { + public Repository getAdapter(Object adaptableObject, Class adapterType) { Repository repository = null; if (adaptableObject instanceof IResource) { IResource resource = (IResource) adaptableObject; - RepositoryMapping repositoryMapping = RepositoryMapping - .getMapping(resource.getProject()); - repository = repositoryMapping.getRepository(); - } else if (adaptableObject instanceof PlatformObject) { - PlatformObject platformObject = (PlatformObject) adaptableObject; - repository = Utils.getAdapter(platformObject, Repository.class); + repository = getRepository(resource); + } else if (adaptableObject instanceof IHistoryView) { + IHistoryView historyView = (IHistoryView) adaptableObject; + IHistoryPage historyPage = historyView.getHistoryPage(); + Object input = historyPage.getInput(); + if (input instanceof RepositoryNode) { + RepositoryNode node = (RepositoryNode) input; + repository = node.getRepository(); + } else if (input instanceof IResource) { + repository = getRepository((IResource) input); + } } else { throw new IllegalStateException(); } @@ -39,10 +43,12 @@ public class GitFlowAdapterFactory implements IAdapterFactory { return repository; } - @SuppressWarnings("unchecked") + private Repository getRepository(IResource resource) { + return getMapping(resource.getProject()).getRepository(); + } + @Override public Class[] getAdapterList() { - return new Class[] { IResource.class, RepositoryTreeNode.class }; + return new Class[] { IResource.class, IHistoryView.class }; } - } diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/menu/DynamicHistoryMenu.java b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/menu/DynamicHistoryMenu.java new file mode 100644 index 0000000000..f73ed06df6 --- /dev/null +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/menu/DynamicHistoryMenu.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (C) 2015, Max Hohenegger <eclipse@hohenegger.eu> + * + * 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.gitflow.ui.internal.menu; + +import java.io.IOException; + +import org.eclipse.egit.core.internal.Utils; +import org.eclipse.egit.gitflow.GitFlowRepository; +import org.eclipse.egit.gitflow.ui.Activator; +import org.eclipse.egit.gitflow.ui.internal.UIText; +import org.eclipse.egit.gitflow.ui.internal.actions.ReleaseStartFromCommitHandler; +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; + +/** + * Start GitFlow release from a specified commit + */ +public class DynamicHistoryMenu extends ContributionItem { + @Override + public void fill(Menu menu, int index) { + GitFlowRepository gfRepo = getRepository(); + try { + if (gfRepo == null || !gfRepo.isDevelop()) { + return; + } + } catch (IOException e) { + Activator.getDefault().getLog().log(Activator.error(e.getMessage())); + return; + } + + RevCommit selectedCommit = getSelectedCommit(); + if (selectedCommit == null) { + return; + } + String startCommitSha1 = selectedCommit.getName(); + Shell activeShell = getActiveShell(); + + ReleaseStartFromCommitHandler listener = new ReleaseStartFromCommitHandler( + gfRepo, startCommitSha1, activeShell); + MenuItem menuItem = new MenuItem(menu, SWT.PUSH, index); + menuItem.setText(NLS.bind( + UIText.DynamicHistoryMenu_startGitflowReleaseFrom, + abbreviate(selectedCommit))); + menuItem.addSelectionListener(listener); + } + + private String abbreviate(RevCommit selectedCommit) { + return selectedCommit.getId().abbreviate(7).name(); + } + + /** + * @return Selected commit + */ + private RevCommit getSelectedCommit() { + ISelection selection = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage().getActivePart() + .getSite().getSelectionProvider().getSelection(); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + IStructuredSelection structSelection = (IStructuredSelection) selection; + Object firstElement = structSelection.getFirstElement(); + if (!(firstElement instanceof RevCommit)) { + return null; + } + return (RevCommit) firstElement; + } + + private Shell getActiveShell() { + return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); + } + + private GitFlowRepository getRepository() { + IWorkbenchPart activePart = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage().getActivePart(); + Repository repository = Utils.getAdapter(activePart, Repository.class); + if (repository == null) { + return null; + } + return new GitFlowRepository(repository); + } +} diff --git a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/uitext.properties b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/uitext.properties index 340dc57bd6..c9aba9e653 100644 --- a/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/uitext.properties +++ b/org.eclipse.egit.gitflow.ui/src/org/eclipse/egit/gitflow/ui/internal/uitext.properties @@ -6,6 +6,10 @@ # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html ############################################################################### +DynamicHistoryMenu_startGitflowReleaseFrom=Start release from commit {0}... +FeatureFinishHandler_Conflicts=Conflicts +FeatureFinishHandler_conflictsWhileMergingFromTo=Conflicts while merging from {0} to {1} +FeatureFinishHandler_featureFinishConflicts=Finishing feature resulted in conflicts. FeatureFinishHandler_finishingFeature=Finishing feature... FeatureRebaseHandler_conflicts=Conflicts FeatureRebaseHandler_rebaseFailed=Rebase failed. @@ -20,12 +24,16 @@ FeatureTrackHandler_noRemoteFeaturesFoundOnTheConfiguredRemote=No features were FeatureTrackHandler_remoteFeatures=Remote features: FeatureTrackHandler_selectFeature=Select Feature FeatureTrackHandler_trackingFeature=Tracking feature... +HotfixFinishHandler_Conflicts=Conflicts HotfixFinishHandler_finishingHotfix=Finishing hotfix... +HotfixFinishHandler_hotfixFinishConflicts=Finishing hotfix resulted in conflicts. HotfixStartHandler_pleaseProvideANameForTheNewHotfix=Please provide a name for the new hotfix. HotfixStartHandler_provideHotfixName=Provide hotfix name HotfixStartHandler_startingNewHotfix=Starting new Hotfix... InitHandler_initializing=Initializing... +ReleaseFinishHandler_Conflicts=Conflicts ReleaseFinishHandler_finishingRelease=Finishing release... +ReleaseFinishHandler_releaseFinishConflicts=Finishing release resulted in conflicts. ReleaseStartHandler_provideANameForTheNewRelease=Please provide a name for the new release. ReleaseStartHandler_provideReleaseName=Provide release name ReleaseStartHandler_startingNewRelease=Starting new Release... @@ -39,3 +47,5 @@ NameValidator_invalidName='%s' is not a valid name. None of the following charac NameValidator_nameAlreadyExists=Name '%s' already exists FeatureCheckoutHandler_cleanupDialog_title=Cannot Rebase Repository ''{0}'' FeatureCheckoutHandler_cleanupDialog_text=You have uncommitted changes. Either commit the changes, stash the changes, or discard the changes by resetting the current branch. +ReleaseFinishOperation_unexpectedConflictsReleaseAborted=Unexpected conflicts while merging to {0}. Finish release aborted. +HotfixFinishOperation_unexpectedConflictsHotfixAborted=Unexpected conflicts while merging to {0}. Finish hotfix aborted. diff --git a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java index 5a33c3c95d..efe1db6e7c 100644 --- a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java +++ b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/GitFlowOperation.java @@ -51,6 +51,12 @@ abstract public class GitFlowOperation implements IEGitOperation { protected GitFlowRepository repository; /** + * the status of the latest merge from this operation + */ + // TODO: Remove from this class. Not all GitFlow operations involve a merge + protected MergeResult mergeResult; + + /** * @param repository */ public GitFlowOperation(GitFlowRepository repository) { @@ -96,16 +102,15 @@ abstract public class GitFlowOperation implements IEGitOperation { * * @param monitor * @param branchName - * @return result of merging back to develop branch * @throws CoreException */ - protected MergeResult finish(IProgressMonitor monitor, String branchName) + protected void finish(IProgressMonitor monitor, String branchName) throws CoreException { try { - MergeResult mergeResult = mergeTo(monitor, branchName, + mergeResult = mergeTo(monitor, branchName, repository.getConfig().getDevelop()); if (!mergeResult.getMergeStatus().isSuccessful()) { - return mergeResult; + return; } Ref branch = repository.findBranch(branchName); @@ -115,8 +120,6 @@ abstract public class GitFlowOperation implements IEGitOperation { } new DeleteBranchOperation(repository.getRepository(), branch, false) .execute(monitor); - - return mergeResult; } catch (IOException e) { throw new RuntimeException(e); } @@ -171,4 +174,12 @@ abstract public class GitFlowOperation implements IEGitOperation { fetchOperation.run(monitor); return fetchOperation.getOperationResult(); } + + /** + * @return The result of the merge this operation performs. May be null, if + * no merge was performed. + */ + public MergeResult getMergeResult() { + return mergeResult; + } } diff --git a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/HotfixFinishOperation.java b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/HotfixFinishOperation.java index 4feb2d4194..8eb8f6ab3f 100644 --- a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/HotfixFinishOperation.java +++ b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/HotfixFinishOperation.java @@ -8,8 +8,6 @@ *******************************************************************************/ package org.eclipse.egit.gitflow.op; -import static org.eclipse.egit.gitflow.Activator.error; - import java.io.IOException; import org.eclipse.core.runtime.CoreException; @@ -17,15 +15,12 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.egit.gitflow.GitFlowRepository; import org.eclipse.egit.gitflow.WrongGitFlowStateException; import org.eclipse.egit.gitflow.internal.CoreText; -import org.eclipse.jgit.api.MergeResult; import org.eclipse.osgi.util.NLS; /** * git flow hotfix finish */ public final class HotfixFinishOperation extends AbstractHotfixOperation { - private MergeResult mergeResult; - /** * finish given hotfix branch * @@ -52,26 +47,16 @@ public final class HotfixFinishOperation extends AbstractHotfixOperation { @Override public void execute(IProgressMonitor monitor) throws CoreException { String hotfixBranchName = repository.getConfig().getHotfixBranchName(versionName); - mergeResult = mergeTo(monitor, hotfixBranchName, - repository.getConfig().getMaster()); - if (!mergeResult.getMergeStatus().isSuccessful()) { - throw new CoreException( - error(CoreText.HotfixFinishOperation_mergeFromHotfixToMasterFailed)); - } - - mergeResult = finish(monitor, hotfixBranchName); + String master = repository.getConfig().getMaster(); + mergeResult = mergeTo(monitor, hotfixBranchName, master); if (!mergeResult.getMergeStatus().isSuccessful()) { + // problems during merge to master => this repository is not in a healthy state return; } + finish(monitor, hotfixBranchName); + // this may result in conflicts, but that's ok safeCreateTag(monitor, versionName, NLS.bind(CoreText.HotfixFinishOperation_hotfix, versionName)); } - - /** - * @return result set after operation was executed - */ - public MergeResult getOperationResult() { - return mergeResult; - } } diff --git a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/ReleaseFinishOperation.java b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/ReleaseFinishOperation.java index 4fcdc1c559..fdc07193bd 100644 --- a/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/ReleaseFinishOperation.java +++ b/org.eclipse.egit.gitflow/src/org/eclipse/egit/gitflow/op/ReleaseFinishOperation.java @@ -48,8 +48,15 @@ public final class ReleaseFinishOperation extends AbstractReleaseOperation { @Override public void execute(IProgressMonitor monitor) throws CoreException { String releaseBranchName = repository.getConfig().getReleaseBranchName(versionName); - mergeTo(monitor, releaseBranchName, repository.getConfig().getMaster()); + String master = repository.getConfig().getMaster(); + mergeResult = mergeTo(monitor, releaseBranchName, master); + if (!mergeResult.getMergeStatus().isSuccessful()) { + // problems during merge to master => this repository is not in a healthy state + return; + } + finish(monitor, releaseBranchName); + // this may result in conflicts, but that's ok safeCreateTag(monitor, repository.getConfig().getVersionTagPrefix() + versionName, NLS.bind(CoreText.ReleaseFinishOperation_releaseOf, versionName)); } diff --git a/org.eclipse.egit.target/egit-4.5-staging.target b/org.eclipse.egit.target/egit-4.5-staging.target index cccc0b8862..2e6b36f64c 100644 --- a/org.eclipse.egit.target/egit-4.5-staging.target +++ b/org.eclipse.egit.target/egit-4.5-staging.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="egit-4.5-staging" sequenceNumber="1432590419"> +<target name="egit-4.5-staging" sequenceNumber="1433163953"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.2.10.v20150310"/> @@ -77,7 +77,7 @@ <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/> <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/> <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20150519210750/repository/"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20150519210750/repository/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.sdk.ide" version="0.0.0"/> diff --git a/org.eclipse.egit.target/egit-4.5-staging.tpd b/org.eclipse.egit.target/egit-4.5-staging.tpd index 8d7fcbc445..59de4d330b 100644 --- a/org.eclipse.egit.target/egit-4.5-staging.tpd +++ b/org.eclipse.egit.target/egit-4.5-staging.tpd @@ -3,6 +3,6 @@ target "egit-4.5-staging" with source configurePhase include "projects/jetty-9.2.10.tpd" include "projects/swtbot-2.1.0.tpd" include "projects/mylyn-latest.tpd" -include "orbit/S20150519210750-Mars-RC2.tpd" +include "orbit/R20150519210750-Mars.tpd" include "releasetrain/staging.tpd" include "projects/easymport.tpd" diff --git a/org.eclipse.egit.target/egit-4.5.target b/org.eclipse.egit.target/egit-4.5.target index 3ef0a82060..28ea89b707 100644 --- a/org.eclipse.egit.target/egit-4.5.target +++ b/org.eclipse.egit.target/egit-4.5.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="egit-4.5" sequenceNumber="1432590370"> +<target name="egit-4.5" sequenceNumber="1433163921"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.2.10.v20150310"/> @@ -77,7 +77,7 @@ <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/> <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/> <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20150519210750/repository/"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20150519210750/repository/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.sdk.ide" version="0.0.0"/> diff --git a/org.eclipse.egit.target/egit-4.5.tpd b/org.eclipse.egit.target/egit-4.5.tpd index 2c51211373..ad3d39b621 100644 --- a/org.eclipse.egit.target/egit-4.5.tpd +++ b/org.eclipse.egit.target/egit-4.5.tpd @@ -3,6 +3,6 @@ target "egit-4.5" with source configurePhase include "projects/jetty-9.2.10.tpd" include "projects/swtbot-2.1.0.tpd" include "projects/mylyn-latest.tpd" -include "orbit/S20150519210750-Mars-RC2.tpd" +include "orbit/R20150519210750-Mars.tpd" include "releasetrain/4.5-mars.tpd" include "projects/easymport.tpd" diff --git a/org.eclipse.egit.target/orbit/S20150519210750-Mars-RC2.tpd b/org.eclipse.egit.target/orbit/R20150519210750-Mars.tpd index 2e84d2d451..6a59551702 100644 --- a/org.eclipse.egit.target/orbit/S20150519210750-Mars-RC2.tpd +++ b/org.eclipse.egit.target/orbit/R20150519210750-Mars.tpd @@ -1,7 +1,7 @@ -target "S20141023165154-Mars-M3" with source configurePhase +target "R20150519210750-Mars" with source configurePhase // see http://download.eclipse.org/tools/orbit/downloads/ -location "http://download.eclipse.org/tools/orbit/downloads/drops/S20150519210750/repository/" { +location "http://download.eclipse.org/tools/orbit/downloads/drops/R20150519210750/repository/" { org.apache.ant [1.9.4.v201504302020,1.9.4.v201504302020] org.apache.ant.source [1.9.4.v201504302020,1.9.4.v201504302020] org.apache.commons.compress [1.6.0.v201310281400,1.6.0.v201310281400] |