Search in sources :

Example 1 with MergeStatus

use of org.eclipse.jgit.api.MergeResult.MergeStatus in project egit by eclipse.

the class FeatureFinishHandler method postMerge.

private void postMerge(final GitFlowRepository gfRepo, final String featureBranch, final boolean squash, final MergeResult mergeResult) {
    Display display = Display.getDefault();
    display.asyncExec(new Runnable() {

        @Override
        public void run() {
            Shell activeShell = Display.getDefault().getActiveShell();
            if (squash && mergeResult.getMergedCommits().length > 1) {
                try {
                    rewordCommitMessage(activeShell, gfRepo);
                } catch (CoreException | IOException e) {
                    throw new RuntimeException(e);
                }
            }
            MergeStatus mergeStatus = mergeResult.getMergeStatus();
            if (MergeStatus.CONFLICTING.equals(mergeStatus)) {
                String develop = gfRepo.getConfig().getDevelop();
                MultiStatus status = createMergeConflictInfo(develop, featureBranch, mergeResult);
                ErrorDialog.openError(null, UIText.FeatureFinishHandler_Conflicts, null, status);
            }
        }
    });
}
Also used : Shell(org.eclipse.swt.widgets.Shell) MergeStatus(org.eclipse.jgit.api.MergeResult.MergeStatus) MultiStatus(org.eclipse.core.runtime.MultiStatus) Display(org.eclipse.swt.widgets.Display)

Example 2 with MergeStatus

use of org.eclipse.jgit.api.MergeResult.MergeStatus in project egit by eclipse.

the class HotfixFinishHandler method execute.

@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
    final GitFlowRepository gfRepo = GitFlowHandlerUtil.getRepository(event);
    if (gfRepo == null) {
        return error(UIText.Handlers_noGitflowRepositoryFound);
    }
    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);
        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 status = createMergeConflictInfo(develop, hotfixBranch, mergeResult);
        ErrorDialog.openError(null, UIText.HotfixFinishHandler_Conflicts, null, status);
    } catch (WrongGitFlowStateException | CoreException | IOException | OperationCanceledException | InterruptedException e) {
        return error(e.getMessage(), e);
    }
    return null;
}
Also used : OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) MergeResult(org.eclipse.jgit.api.MergeResult) MultiStatus(org.eclipse.core.runtime.MultiStatus) IJobManager(org.eclipse.core.runtime.jobs.IJobManager) IOException(java.io.IOException) CoreException(org.eclipse.core.runtime.CoreException) MergeStatus(org.eclipse.jgit.api.MergeResult.MergeStatus) WrongGitFlowStateException(org.eclipse.egit.gitflow.WrongGitFlowStateException) GitFlowRepository(org.eclipse.egit.gitflow.GitFlowRepository) HotfixFinishOperation(org.eclipse.egit.gitflow.op.HotfixFinishOperation)

Example 3 with MergeStatus

use of org.eclipse.jgit.api.MergeResult.MergeStatus in project fabric8 by jboss-fuse.

the class DefaultPullPushPolicy method doPull.

@Override
public synchronized PullPolicyResult doPull(GitContext context, CredentialsProvider credentialsProvider, boolean allowVersionDelete, boolean allowPush, int timeoutInSeconds) {
    Repository repository = git.getRepository();
    StoredConfig config = repository.getConfig();
    String remoteUrl = config.getString("remote", remoteRef, "url");
    if (remoteUrl == null) {
        LOGGER.info("No remote repository defined, so not doing a pull");
        return new AbstractPullPolicyResult();
    }
    LOGGER.info("Performing a pull on remote URL: {}", remoteUrl);
    // Get local and remote branches
    Map<String, Ref> localBranches = new HashMap<String, Ref>();
    Map<String, Ref> remoteBranches = new HashMap<String, Ref>();
    Set<String> allBranches = new HashSet<String>();
    Exception lastException = null;
    try {
        // when trying to fast-forward to commit done upstream between fetch and ls-remote!
        for (Ref ref : git.lsRemote().setTimeout(timeoutInSeconds).setCredentialsProvider(credentialsProvider).setTags(false).setHeads(true).setRemote(remoteRef).call()) {
            if (ref.getName().startsWith("refs/heads/")) {
                String name = ref.getName().substring(("refs/heads/").length());
                remoteBranches.put(name, ref);
                allBranches.add(name);
            }
        }
        git.fetch().setTimeout(timeoutInSeconds).setCredentialsProvider(credentialsProvider).setTagOpt(TagOpt.FETCH_TAGS).setRemote(remoteRef).call();
    } catch (Exception ex) {
        lastException = ex;
    }
    // No meaningful processing after GitAPIException
    if (lastException != null) {
        logPullException(lastException);
        return new AbstractPullPolicyResult(lastException);
    }
    try {
        // list local branches
        for (Ref ref : git.branchList().setListMode(ListBranchCommand.ListMode.ALL).call()) {
            // }
            if (ref.getName().startsWith("refs/heads/")) {
                String name = ref.getName().substring(("refs/heads/").length());
                localBranches.put(name, ref);
                allBranches.add(name);
            }
        }
        Map<String, BranchChange> localUpdate = new HashMap<>();
        boolean remoteUpdate = false;
        Set<String> versions = new TreeSet<>();
        // Remote repository has no branches, force a push
        if (remoteBranches.isEmpty()) {
            LOGGER.info("Pulled from an empty remote repository");
            return new AbstractPullPolicyResult(versions, localUpdate, !localBranches.isEmpty(), null);
        } else {
            LOGGER.debug("Processing remote branches: {}", remoteBranches);
        }
        // Verify master branch and do a checkout of it when we have it locally (already)
        IllegalStateAssertion.assertTrue(remoteBranches.containsKey(GitHelpers.MASTER_BRANCH), "Remote repository does not have a master branch");
        // Iterate over all local/remote branches
        for (String branch : allBranches) {
            // Delete a local branch that does not exist remotely, but not master
            boolean allowDelete = allowVersionDelete && !GitHelpers.MASTER_BRANCH.equals(branch);
            if (localBranches.containsKey(branch) && !remoteBranches.containsKey(branch)) {
                if (allowDelete) {
                    String remotebranchRef = String.format("remotes/%s/%s", remoteRef, branch);
                    LOGGER.info("Deleting local branch: {} and local reference to remote branch: {}", branch, remotebranchRef);
                    // which can't be deleted
                    if (branch.equals(git.getRepository().getBranch())) {
                        // to remove not-tracked files
                        git.clean().setCleanDirectories(true).call();
                        // for file permissions
                        git.reset().setMode(ResetCommand.ResetType.MIXED).call();
                        // for other changes
                        git.reset().setMode(ResetCommand.ResetType.HARD).call();
                        git.checkout().setName("master").call();
                    }
                    git.branchDelete().setBranchNames(branch, remotebranchRef).setForce(true).call();
                    localUpdate.put(branch, new BranchChange(branch).removed());
                } else {
                    remoteUpdate = true;
                }
            } else // Create a local branch that exists remotely
            if (!localBranches.containsKey(branch) && remoteBranches.containsKey(branch)) {
                LOGGER.info("Adding new local branch: {}", branch);
                git.checkout().setCreateBranch(true).setName(branch).setStartPoint(remoteRef + "/" + branch).setUpstreamMode(SetupUpstreamMode.TRACK).setForce(true).call();
                versions.add(branch);
                localUpdate.put(branch, new BranchChange(branch).created());
            } else // Update a local branch that also exists remotely
            if (localBranches.containsKey(branch) && remoteBranches.containsKey(branch)) {
                ObjectId localObjectId = localBranches.get(branch).getObjectId();
                ObjectId remoteObjectId = remoteBranches.get(branch).getObjectId();
                String localCommit = localObjectId.getName();
                String remoteCommit = remoteObjectId.getName();
                if (!localCommit.equals(remoteCommit)) {
                    git.clean().setCleanDirectories(true).call();
                    git.checkout().setName(branch).setForce(true).call();
                    MergeResult mergeResult = git.merge().setFastForward(FastForwardMode.FF_ONLY).include(remoteObjectId).call();
                    MergeStatus mergeStatus = mergeResult.getMergeStatus();
                    LOGGER.info("Updating local branch {} with status: {} ({}..{})", branch, mergeStatus, localCommit, remoteCommit);
                    if (mergeStatus == MergeStatus.FAST_FORWARD) {
                        localUpdate.put(branch, new BranchChange(branch).updated(localObjectId, remoteObjectId, "fast forward"));
                    } else if (mergeStatus == MergeStatus.ALREADY_UP_TO_DATE) {
                        if (allowPush) {
                            LOGGER.info("Remote branch {} is behind local version - changes will be pushed", branch);
                            remoteUpdate = true;
                        } else {
                            LOGGER.info("Remote branch {} is behind local version - changes won't be pushed - restoring remote tracking branch", branch);
                            GitHelpers.createOrCheckoutBranch(git, GitHelpers.MASTER_BRANCH, GitHelpers.REMOTE_ORIGIN);
                            git.branchDelete().setBranchNames(branch).setForce(true).call();
                            git.checkout().setCreateBranch(true).setName(branch).setStartPoint(remoteRef + "/" + branch).setUpstreamMode(SetupUpstreamMode.TRACK).setForce(true).call();
                            localUpdate.put(branch, new BranchChange(branch).updated(localObjectId, remoteObjectId, "reset"));
                        }
                    } else if (mergeStatus == MergeStatus.ABORTED) {
                        // failure to merge using FastForwardMode.FF_ONLY always ends with MergeStatus.ABORTED
                        RebaseResult.Status rebaseStatus = null;
                        if (allowPush) {
                            LOGGER.info("Cannot fast forward branch {}, attempting rebase", branch);
                            RebaseResult rebaseResult = git.rebase().setUpstream(remoteCommit).call();
                            rebaseStatus = rebaseResult.getStatus();
                        }
                        if (rebaseStatus == RebaseResult.Status.OK) {
                            LOGGER.info("Rebase successful for branch {}", branch);
                            localUpdate.put(branch, new BranchChange(branch).updated(localObjectId, remoteObjectId, "rebase"));
                            remoteUpdate = true;
                        } else {
                            if (allowPush) {
                                LOGGER.warn("Rebase on branch {} failed, restoring remote tracking branch", branch);
                                git.rebase().setOperation(Operation.ABORT).call();
                            } else {
                                LOGGER.info("Restoring remote tracking branch {}", branch);
                            }
                            GitHelpers.createOrCheckoutBranch(git, GitHelpers.MASTER_BRANCH, GitHelpers.REMOTE_ORIGIN, remoteCommit);
                            git.branchDelete().setBranchNames(branch).setForce(true).call();
                            git.checkout().setCreateBranch(true).setName(branch).setStartPoint(remoteRef + "/" + branch).setUpstreamMode(SetupUpstreamMode.TRACK).setForce(true).call();
                            localUpdate.put(branch, new BranchChange(branch).updated(localObjectId, remoteObjectId, "reset"));
                        }
                    }
                } else if (!git.status().call().isClean()) {
                    LOGGER.info("Local branch {} is up to date, but not clean. Cleaning working copy now.", branch);
                    // to remove not-tracked files
                    git.clean().setCleanDirectories(true).call();
                    // for file permissions
                    git.reset().setMode(ResetCommand.ResetType.MIXED).call();
                    // for other changes
                    git.reset().setMode(ResetCommand.ResetType.HARD).call();
                }
                versions.add(branch);
            }
        }
        if (localUpdate.size() > 0) {
            if (--mergesWithoutGC < 0) {
                mergesWithoutGC = MAX_MERGES_WITHOUT_GC;
                LOGGER.info("Performing 'git gc' after {} merges", MAX_MERGES_WITHOUT_GC);
                try {
                    git.gc().setAggressive(true).call();
                } catch (Exception e) {
                    LOGGER.warn("Problem invoking 'git gc': {}", e.getMessage());
                }
            }
        }
        PullPolicyResult result = new AbstractPullPolicyResult(versions, localUpdate, remoteUpdate, null);
        LOGGER.info("Pull result: {}", result);
        return result;
    } catch (Exception ex) {
        LOGGER.error(ex.getMessage(), ex);
        return new AbstractPullPolicyResult(ex);
    }
}
Also used : HashMap(java.util.HashMap) ObjectId(org.eclipse.jgit.lib.ObjectId) MergeResult(org.eclipse.jgit.api.MergeResult) SocketTimeoutException(java.net.SocketTimeoutException) NoRemoteRepositoryException(org.eclipse.jgit.errors.NoRemoteRepositoryException) ConnectException(java.net.ConnectException) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) StoredConfig(org.eclipse.jgit.lib.StoredConfig) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) TreeSet(java.util.TreeSet) MergeStatus(org.eclipse.jgit.api.MergeResult.MergeStatus) RebaseResult(org.eclipse.jgit.api.RebaseResult) HashSet(java.util.HashSet)

Example 4 with MergeStatus

use of org.eclipse.jgit.api.MergeResult.MergeStatus in project egit by eclipse.

the class ReleaseFinishHandler method execute.

@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
    final GitFlowRepository gfRepo = GitFlowHandlerUtil.getRepository(event);
    if (gfRepo == null) {
        return error(UIText.Handlers_noGitflowRepositoryFound);
    }
    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);
        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 status = createMergeConflictInfo(develop, releaseBranch, mergeResult);
        ErrorDialog.openError(null, UIText.ReleaseFinishHandler_Conflicts, null, status);
    } catch (WrongGitFlowStateException | CoreException | IOException | OperationCanceledException | InterruptedException e) {
        return error(e.getMessage(), e);
    }
    return null;
}
Also used : ReleaseFinishOperation(org.eclipse.egit.gitflow.op.ReleaseFinishOperation) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) MergeResult(org.eclipse.jgit.api.MergeResult) MultiStatus(org.eclipse.core.runtime.MultiStatus) IJobManager(org.eclipse.core.runtime.jobs.IJobManager) IOException(java.io.IOException) CoreException(org.eclipse.core.runtime.CoreException) MergeStatus(org.eclipse.jgit.api.MergeResult.MergeStatus) WrongGitFlowStateException(org.eclipse.egit.gitflow.WrongGitFlowStateException) GitFlowRepository(org.eclipse.egit.gitflow.GitFlowRepository)

Example 5 with MergeStatus

use of org.eclipse.jgit.api.MergeResult.MergeStatus in project egit by eclipse.

the class MergeResultDialog method createDialogArea.

@Override
public Control createDialogArea(final Composite parent) {
    final Composite composite = (Composite) super.createDialogArea(parent);
    GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    composite.setLayout(gridLayout);
    // result
    Label resultLabel = new Label(composite, SWT.NONE);
    resultLabel.setText(UIText.MergeResultDialog_result);
    resultLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
    Text resultText = new Text(composite, SWT.READ_ONLY);
    MergeStatus status = mergeResult.getMergeStatus();
    resultText.setText(status.toString());
    resultText.setSelection(resultText.getCaretPosition());
    resultText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    if (status == MergeStatus.FAILED) {
        resultText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
        StringBuilder paths = new StringBuilder();
        Label pathsLabel = new Label(composite, SWT.NONE);
        pathsLabel.setText(UIText.MergeResultDialog_failed);
        pathsLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
        Text pathsText = new Text(composite, SWT.READ_ONLY);
        pathsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
        Set<Entry<String, MergeFailureReason>> failedPaths = mergeResult.getFailingPaths().entrySet();
        int n = 0;
        for (Map.Entry<String, MergeFailureReason> e : failedPaths) {
            if (n > 0)
                paths.append(Text.DELIMITER);
            paths.append(e.getValue());
            // $NON-NLS-1$
            paths.append("\t");
            paths.append(e.getKey());
            n++;
            if (n > 10 && failedPaths.size() > 15)
                break;
        }
        if (n < failedPaths.size()) {
            paths.append(Text.DELIMITER);
            paths.append(MessageFormat.format(UIText.MergeResultDialog_nMore, Integer.valueOf(n - failedPaths.size())));
        }
        pathsText.setText(paths.toString());
    }
    if (status == MergeStatus.FAST_FORWARD || status == MergeStatus.FAST_FORWARD_SQUASHED || status == MergeStatus.MERGED) {
        // new head
        Label newHeadLabel = new Label(composite, SWT.NONE);
        newHeadLabel.setText(UIText.MergeResultDialog_newHead);
        newHeadLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
        Text newHeadText = new Text(composite, SWT.READ_ONLY);
        ObjectId newHead = mergeResult.getNewHead();
        if (newHead != null)
            newHeadText.setText(getCommitMessage(newHead) + SPACE + abbreviate(mergeResult.getNewHead(), true));
        newHeadText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    }
    // Merge Input
    Label mergeInputLabel = new Label(composite, SWT.NONE);
    mergeInputLabel.setText(UIText.MergeResultDialog_mergeInput);
    GridDataFactory.fillDefaults().align(SWT.LEAD, SWT.CENTER).span(2, 1).applyTo(mergeInputLabel);
    TableViewer viewer = new TableViewer(composite);
    viewer.setContentProvider(new IStructuredContentProvider() {

        @Override
        public void dispose() {
        // empty
        }

        @Override
        public void inputChanged(Viewer theViewer, Object oldInput, Object newInput) {
        // empty
        }

        @Override
        public Object[] getElements(Object inputElement) {
            return getCommits(mergeResult.getMergedCommits());
        }
    });
    final IStyledLabelProvider styleProvider = new IStyledLabelProvider() {

        private final WorkbenchLabelProvider wrapped = new WorkbenchLabelProvider();

        @Override
        public void removeListener(ILabelProviderListener listener) {
        // Empty
        }

        @Override
        public boolean isLabelProperty(Object element, String property) {
            return false;
        }

        @Override
        public void dispose() {
            wrapped.dispose();
        }

        @Override
        public void addListener(ILabelProviderListener listener) {
        // Empty
        }

        @Override
        public StyledString getStyledText(Object element) {
            // supported
            if (element instanceof RepositoryCommit)
                return ((RepositoryCommit) element).getStyledText(element);
            return new StyledString(wrapped.getText(element));
        }

        @Override
        public Image getImage(Object element) {
            return wrapped.getImage(element);
        }
    };
    viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(styleProvider));
    applyDialogFont(composite);
    GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).span(2, 1).applyTo(viewer.getControl());
    viewer.setInput(mergeResult);
    new OpenAndLinkWithEditorHelper(viewer) {

        @Override
        protected void linkToEditor(ISelection selection) {
        // Not supported
        }

        @Override
        protected void open(ISelection selection, boolean activate) {
            handleOpen(selection, OpenStrategy.activateOnOpen());
        }

        @Override
        protected void activate(ISelection selection) {
            handleOpen(selection, true);
        }

        private void handleOpen(ISelection selection, boolean activateOnOpen) {
            if (selection instanceof IStructuredSelection)
                for (Object element : ((IStructuredSelection) selection).toArray()) if (element instanceof RepositoryCommit)
                    CommitEditor.openQuiet((RepositoryCommit) element, activateOnOpen);
        }
    };
    return composite;
}
Also used : OpenAndLinkWithEditorHelper(org.eclipse.ui.OpenAndLinkWithEditorHelper) WorkbenchLabelProvider(org.eclipse.ui.model.WorkbenchLabelProvider) Label(org.eclipse.swt.widgets.Label) TableViewer(org.eclipse.jface.viewers.TableViewer) Viewer(org.eclipse.jface.viewers.Viewer) StyledString(org.eclipse.jface.viewers.StyledString) IStructuredSelection(org.eclipse.jface.viewers.IStructuredSelection) GridLayout(org.eclipse.swt.layout.GridLayout) Entry(java.util.Map.Entry) ISelection(org.eclipse.jface.viewers.ISelection) DelegatingStyledCellLabelProvider(org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider) Composite(org.eclipse.swt.widgets.Composite) ObjectId(org.eclipse.jgit.lib.ObjectId) Text(org.eclipse.swt.widgets.Text) UIText(org.eclipse.egit.ui.internal.UIText) StyledString(org.eclipse.jface.viewers.StyledString) MergeFailureReason(org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason) RepositoryCommit(org.eclipse.egit.ui.internal.commit.RepositoryCommit) ILabelProviderListener(org.eclipse.jface.viewers.ILabelProviderListener) MergeStatus(org.eclipse.jgit.api.MergeResult.MergeStatus) IStyledLabelProvider(org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider) GridData(org.eclipse.swt.layout.GridData) IStructuredContentProvider(org.eclipse.jface.viewers.IStructuredContentProvider) Map(java.util.Map) TableViewer(org.eclipse.jface.viewers.TableViewer)

Aggregations

MergeStatus (org.eclipse.jgit.api.MergeResult.MergeStatus)5 MultiStatus (org.eclipse.core.runtime.MultiStatus)3 MergeResult (org.eclipse.jgit.api.MergeResult)3 IOException (java.io.IOException)2 CoreException (org.eclipse.core.runtime.CoreException)2 OperationCanceledException (org.eclipse.core.runtime.OperationCanceledException)2 IJobManager (org.eclipse.core.runtime.jobs.IJobManager)2 GitFlowRepository (org.eclipse.egit.gitflow.GitFlowRepository)2 WrongGitFlowStateException (org.eclipse.egit.gitflow.WrongGitFlowStateException)2 ObjectId (org.eclipse.jgit.lib.ObjectId)2 ConnectException (java.net.ConnectException)1 SocketTimeoutException (java.net.SocketTimeoutException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 Entry (java.util.Map.Entry)1 TreeSet (java.util.TreeSet)1 HotfixFinishOperation (org.eclipse.egit.gitflow.op.HotfixFinishOperation)1 ReleaseFinishOperation (org.eclipse.egit.gitflow.op.ReleaseFinishOperation)1 UIText (org.eclipse.egit.ui.internal.UIText)1