/* * Copyright 2000-2009 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.community.intellij.plugins.communitycase.merge; import com.intellij.history.Label; import com.intellij.history.LocalHistory; import com.intellij.ide.util.ElementsChooser; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.AbstractVcsHelper; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.TransactionRunnable; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx; import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vcs.update.ActionInfo; import com.intellij.openapi.vcs.update.FileGroup; import com.intellij.openapi.vcs.update.UpdateInfoTree; import com.intellij.openapi.vcs.update.UpdatedFiles; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.community.intellij.plugins.communitycase.Vcs; import org.community.intellij.plugins.communitycase.actions.RepositoryAction; import org.community.intellij.plugins.communitycase.i18n.Bundle; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Utilities for merge */ public class MergeUtil { /** * The item representing default strategy */ public static final String DEFAULT_STRATEGY = Bundle.getString("merge.default.strategy"); /** * A private constructor for utility class */ private MergeUtil() { } /** * Get a list of merge strategies for the specified branch count * * @param branchCount a number of branches to merge * @return an array of strategy names */ @NonNls public static String[] getMergeStrategies(int branchCount) { if (branchCount < 0) { throw new IllegalArgumentException("Branch count must be non-negative: " + branchCount); } switch (branchCount) { case 0: return new String[]{DEFAULT_STRATEGY}; case 1: return new String[]{DEFAULT_STRATEGY, "resolve", "recursive", "octopus", "ours", "subtree"}; default: return new String[]{DEFAULT_STRATEGY, "octopus", "ours"}; } } /** * Initialize no commit checkbox (for both merge and pull dialog) * * @param addLogInformationCheckBox a log information checkbox * @param commitMessage a commit message text field or null * @param noCommitCheckBox a no commit checkbox to configure */ public static void setupNoCommitCheckbox(final JCheckBox addLogInformationCheckBox, final JTextField commitMessage, final JCheckBox noCommitCheckBox) { noCommitCheckBox.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { final boolean selected = noCommitCheckBox.isSelected(); if (commitMessage != null) { commitMessage.setEnabled(!selected); } if (selected) { addLogInformationCheckBox.setSelected(false); } addLogInformationCheckBox.setEnabled(!selected); } }); } /** * Setup strategies combobox. The set of strategies changes according to amount of selected elements in branchChooser. * * @param branchChooser a branch chooser * @param strategy a strategy selector */ public static void setupStrategies(final ElementsChooser<String> branchChooser, final JComboBox strategy) { final ElementsChooser.ElementsMarkListener<String> listener = new ElementsChooser.ElementsMarkListener<String>() { private void updateStrategies(final List<String> elements) { strategy.removeAllItems(); for (String s : getMergeStrategies(elements.size())) { strategy.addItem(s); } strategy.setSelectedItem(DEFAULT_STRATEGY); } public void elementMarkChanged(final String element, final boolean isMarked) { final List<String> elements = branchChooser.getMarkedElements(); if (elements.size() == 0) { strategy.setEnabled(false); updateStrategies(elements); } else { strategy.setEnabled(true); updateStrategies(elements); } } }; listener.elementMarkChanged(null, true); branchChooser.addElementsMarkListener(listener); } /** * Show updates caused by git operation * * @param project the context project * @param exceptions the exception list * @param root the git root * @param currentRev the revision before update * @param beforeLabel the local history label before update * @param actionName the action name * @param actionInfo the information about the action */ public static void showUpdates(RepositoryAction action, final Project project, final List<VcsException> exceptions, final VirtualFile root, final VcsRevisionNumber currentRev, final Label beforeLabel, final String actionName, final ActionInfo actionInfo) { final UpdatedFiles files = UpdatedFiles.create(); MergeChangeCollector collector = new MergeChangeCollector(project, root, currentRev, files); collector.collect(exceptions); if (exceptions.size() != 0) { return; } action.delayTask(new TransactionRunnable() { public void run(List<VcsException> exceptionList) { ProjectLevelVcsManagerEx manager = (ProjectLevelVcsManagerEx)ProjectLevelVcsManager.getInstance(project); UpdateInfoTree tree = manager.showUpdateProjectInfo(files, actionName, actionInfo, false); tree.setBefore(beforeLabel); tree.setAfter(LocalHistory.getInstance().putSystemLabel(project, "After update")); } }); final Collection<String> unmergedNames = files.getGroupById(FileGroup.MERGED_WITH_CONFLICT_ID).getFiles(); if (!unmergedNames.isEmpty()) { action.delayTask(new TransactionRunnable() { public void run(List<VcsException> exceptionList) { LocalFileSystem lfs = LocalFileSystem.getInstance(); final ArrayList<VirtualFile> unmerged = new ArrayList<VirtualFile>(); for (String fileName : unmergedNames) { VirtualFile f = lfs.findFileByPath(fileName); if (f != null) { unmerged.add(f); } } AbstractVcsHelper.getInstance(project).showMergeDialog(unmerged, Vcs.getInstance(project).getMergeProvider()); } }); } } /** * @param root the vcs root * @return the path to merge head file */ @Nullable private static File getMergeHead(VirtualFile root) { File gitDir = new File(VfsUtil.virtualToIoFile(root), ".git"); File f = new File(gitDir, "MERGE_HEAD"); if (f.exists()) { return f; } return null; } /** * Checks if the merge is in the progress for the specified git root * * @param root the git root * @return true if the merge_head file presents in the root */ public static boolean isMergeInTheProgress(VirtualFile root) { return getMergeHead(root) != null; } }