From 8084cb06ef8b756bc7a6976f8f7ca681a52344ce Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Fri, 7 Mar 2014 21:57:12 +0400 Subject: [PATCH] Rebase feature for update project implemented *pull with update or rebase args executed; *continue and abort rebase actions added; *conflicts resolved until rebase continue command finished successfully or cancelled; *rebase state added to repository updater,reader and updated files; *update project dialog changed --- plugins/hg4idea/src/META-INF/plugin.xml | 3 + .../hg4idea/action/HgAbortRebaseAction.java | 50 +++++++++++++ .../action/HgAbstractGlobalAction.java | 15 +++- .../hg4idea/action/HgBranchPopupActions.java | 2 +- .../action/HgContinueRebaseAction.java | 50 +++++++++++++ .../hg4idea/action/HgProcessRebaseAction.java | 32 +++++++++ .../org/zmlx/hg4idea/action/HgPullAction.java | 2 - .../zmlx/hg4idea/command/HgPullCommand.java | 27 ++++--- .../zmlx/hg4idea/command/HgRebaseCommand.java | 11 ++- .../provider/update/HgConflictResolver.java | 36 ++++++---- .../provider/update/HgRegularUpdater.java | 72 ++++++++++++------- .../hg4idea/provider/update/HgUpdater.java | 26 +++---- .../zmlx/hg4idea/repo/HgRepositoryFiles.java | 7 ++ .../zmlx/hg4idea/repo/HgRepositoryReader.java | 7 ++ .../hg4idea/repo/HgRepositoryUpdater.java | 5 ++ .../org/zmlx/hg4idea/ui/HgUpdateDialog.form | 59 --------------- .../org/zmlx/hg4idea/ui/HgUpdateDialog.java | 69 +++++++++++------- .../src/org/zmlx/hg4idea/util/HgUtil.java | 2 +- .../org/zmlx/hg4idea/test/HgUpdateTest.java | 1 - 19 files changed, 317 insertions(+), 159 deletions(-) create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbortRebaseAction.java create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgContinueRebaseAction.java create mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java delete mode 100644 plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.form diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml index f0ce13c23b43..d47b955104be 100644 --- a/plugins/hg4idea/src/META-INF/plugin.xml +++ b/plugins/hg4idea/src/META-INF/plugin.xml @@ -77,6 +77,9 @@ + + + diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbortRebaseAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbortRebaseAction.java new file mode 100644 index 000000000000..e0a972a46d81 --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbortRebaseAction.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 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.zmlx.hg4idea.action; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.zmlx.hg4idea.command.HgRebaseCommand; +import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.repo.HgRepository; +import org.zmlx.hg4idea.util.HgErrorUtil; + +import java.util.Collection; + +public class HgAbortRebaseAction extends HgProcessRebaseAction { + + @Override + protected void execute(@NotNull final Project project, + @NotNull Collection repositories, + @Nullable final HgRepository selectedRepo) { + + new Task.Backgroundable(project, "Abort Rebasing...") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + if (selectedRepo != null) { + HgRebaseCommand rebaseCommand = new HgRebaseCommand(project, selectedRepo.getRoot()); + HgCommandResult result = rebaseCommand.abortRebase(); + if (HgErrorUtil.isAbort(result)) { + new HgCommandResultNotifier(project).notifyError(result, "Hg Error", "Couldn't abort rebasing"); + } + } + } + }.queue(); + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java index 9984facc8037..d38bc7bfc6a7 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java @@ -89,7 +89,7 @@ abstract class HgAbstractGlobalAction extends AnAction { } } - public static boolean isEnabled(AnActionEvent e) { + public boolean isEnabled(AnActionEvent e) { Project project = e.getData(CommonDataKeys.PROJECT); if (project == null) { return false; @@ -101,4 +101,17 @@ abstract class HgAbstractGlobalAction extends AnAction { } return true; } + + @Nullable + public static HgRepository getSelectedRepositoryFromEvent(AnActionEvent e) { + final DataContext dataContext = e.getDataContext(); + final Project project = CommonDataKeys.PROJECT.getData(dataContext); + if (project == null) { + return null; + } + VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE); + HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(project); + return file != null ? repositoryManager.getRepositoryForFile(file) : HgUtil.getCurrentRepository(project); + } + } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java index 01627240d8e4..62d5981e55f7 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java @@ -221,7 +221,7 @@ public class HgBranchPopupActions { e.getPresentation().setEnabled(false); e.getPresentation().setDescription("Checkout of a new branch is not possible before the first commit."); } - else if (Repository.State.MERGING.equals(myRepository.getState())) { + else if (!Repository.State.NORMAL.equals(myRepository.getState())) { e.getPresentation().setEnabled(false); } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgContinueRebaseAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgContinueRebaseAction.java new file mode 100644 index 000000000000..ed53d76cb86d --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgContinueRebaseAction.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 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.zmlx.hg4idea.action; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.zmlx.hg4idea.command.HgRebaseCommand; +import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.repo.HgRepository; +import org.zmlx.hg4idea.util.HgErrorUtil; + +import java.util.Collection; + +public class HgContinueRebaseAction extends HgProcessRebaseAction { + + @Override + protected void execute(@NotNull final Project project, + @NotNull Collection repositories, + @Nullable final HgRepository selectedRepo) { + + new Task.Backgroundable(project, "Continue Rebasing...") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + if (selectedRepo != null) { + HgRebaseCommand rebaseCommand = new HgRebaseCommand(project, selectedRepo.getRoot()); + HgCommandResult result = rebaseCommand.continueRebase(); + if (HgErrorUtil.isAbort(result)) { + new HgCommandResultNotifier(project).notifyError(result, "Hg Error", "Couldn't continue rebasing"); + } + } + } + }.queue(); + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java new file mode 100644 index 000000000000..342369f0a9bb --- /dev/null +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 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.zmlx.hg4idea.action; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import org.zmlx.hg4idea.repo.HgRepository; + +public abstract class HgProcessRebaseAction extends HgAbstractGlobalAction { + + protected static boolean isRebasing(AnActionEvent e) { + HgRepository repository = HgAbstractGlobalAction.getSelectedRepositoryFromEvent(e); + return repository != null && repository.getState() == HgRepository.State.REBASING; + } + + @Override + public boolean isEnabled(AnActionEvent e) { + return super.isEnabled(e) && isRebasing(e); + } +} diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java index 557d3cfab286..0d1f79b7f488 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java @@ -51,8 +51,6 @@ public class HgPullAction extends HgAbstractGlobalAction { project, dialog.getRepository() ); command.setSource(dialog.getSource()); - command.setRebase(false); - command.setUpdate(false); command.execute(); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPullCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPullCommand.java index 3be5904b379e..1d17cbcf7b44 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPullCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgPullCommand.java @@ -12,7 +12,6 @@ // limitations under the License. package org.zmlx.hg4idea.command; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -27,15 +26,17 @@ import java.util.LinkedList; import java.util.List; public class HgPullCommand { + public static int ERROR = -1; + public static int UNRESOLVED = 1; + public static int SUCCESS = 0; private final Project project; private final VirtualFile repo; private String source; private String revision; - private boolean update = true; - private boolean rebase = !update; - private static final Logger LOG = Logger.getInstance(HgPullCommand.class); + private boolean update; + private boolean rebase; public HgPullCommand(Project project, @NotNull VirtualFile repo) { this.project = project; @@ -58,7 +59,7 @@ public class HgPullCommand { this.source = source; } - public boolean execute() { + public int execute() { List arguments = new LinkedList(); if (update) { arguments.add("--update"); @@ -79,13 +80,19 @@ public class HgPullCommand { if (HgErrorUtil.isAuthorizationError(result)) { new HgCommandResultNotifier(project) .notifyError(result, "Authorization required", "http authorization required for " + source + ""); - return false; - } else if (HgErrorUtil.hasErrorsInCommandExecution(result)) { + return ERROR; + } + else if (HgErrorUtil.isAbort(result) || result.getExitValue() > 1) { //if result == null - > isAbort returns true new HgCommandResultNotifier(project).notifyError(result, "", "Pull failed"); - return false; - } else { + return ERROR; + } + else if (result.getExitValue() == 1) { + return UNRESOLVED; + } + else { project.getMessageBus().syncPublisher(HgVcs.REMOTE_TOPIC).update(project, null); - return true; + return SUCCESS; } } + } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java index 9f9fd265047f..4e61752504e0 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgRebaseCommand.java @@ -17,6 +17,7 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgVcs; import org.zmlx.hg4idea.execution.HgCommandExecutor; +import org.zmlx.hg4idea.execution.HgCommandResult; import java.util.Arrays; @@ -30,9 +31,15 @@ public class HgRebaseCommand { this.repo = repo; } - public void continueRebase() { - new HgCommandExecutor(project).execute(repo, "rebase", Arrays.asList("--continue"), null); + public HgCommandResult continueRebase() { + HgCommandResult result = new HgCommandExecutor(project).executeInCurrentThread(repo, "rebase", Arrays.asList("--continue"), null); project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null); + return result; } + public HgCommandResult abortRebase() { + HgCommandResult result = new HgCommandExecutor(project).executeInCurrentThread(repo, "rebase", Arrays.asList("--abort"), null); + project.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(project, null); + return result; + } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgConflictResolver.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgConflictResolver.java index 87e346646c3e..aac490b24b79 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgConflictResolver.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgConflictResolver.java @@ -46,7 +46,25 @@ public final class HgConflictResolver { } public void resolve(final VirtualFile repo) { - Map resolves = new HgResolveCommand(myProject).getListSynchronously(repo); + final List conflicts = findConflicts(myProject, updatedFiles, repo); + + if (conflicts.isEmpty()) { + return; + } + + final HgVcs vcs = HgVcs.getInstance(myProject); + if (vcs == null) { + return; + } + ApplicationManager.getApplication().invokeAndWait(new Runnable() { + public void run() { + AbstractVcsHelper.getInstance(myProject).showMergeDialog(conflicts, vcs.getMergeProvider()); + } + }, ModalityState.defaultModalityState()); + } + + public static List findConflicts(final Project project, final UpdatedFiles updatedFiles, VirtualFile repo) { + Map resolves = new HgResolveCommand(project).getListSynchronously(repo); final List conflicts = new ArrayList(); for (Map.Entry entry : resolves.entrySet()) { File file = entry.getKey().getFile(); @@ -65,21 +83,9 @@ public final class HgConflictResolver { updatedFiles.getGroupById(FileGroup.UPDATED_ID).remove(file.getAbsolutePath()); //TODO get the correct revision to pass to the UpdatedFiles updatedFiles.getGroupById(fileGroupId) - .add(file.getPath(), HgVcs.VCS_NAME, null); + .add(file.getPath(), HgVcs.VCS_NAME, null); } } - - if (conflicts.isEmpty()) { - return; - } - - final HgVcs vcs = HgVcs.getInstance(myProject); - if (vcs == null) { return; } - ApplicationManager.getApplication().invokeAndWait(new Runnable() { - public void run() { - AbstractVcsHelper.getInstance(myProject).showMergeDialog(conflicts, vcs.getMergeProvider()); - } - }, ModalityState.defaultModalityState()); + return conflicts; } - } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java index 355405f33e7f..127a9207024e 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgRegularUpdater.java @@ -23,9 +23,11 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.zmlx.hg4idea.*; +import org.zmlx.hg4idea.action.HgCommandResultNotifier; import org.zmlx.hg4idea.command.*; import org.zmlx.hg4idea.execution.HgCommandException; import org.zmlx.hg4idea.execution.HgCommandResult; +import org.zmlx.hg4idea.util.HgErrorUtil; import org.zmlx.hg4idea.util.HgUtil; import java.util.ArrayList; @@ -47,12 +49,8 @@ public class HgRegularUpdater implements HgUpdater { this.updateConfiguration = configuration; } - private boolean shouldPull() { - return updateConfiguration.shouldPull(); - } - - private boolean shouldUpdate() { - return updateConfiguration.shouldUpdate(); + private boolean shouldRebase() { + return updateConfiguration.shouldRebase(); } private boolean shouldMerge() { @@ -88,27 +86,29 @@ public class HgRegularUpdater implements HgUpdater { // throw new VcsException("working dir not at branch tip (use \"Update to...\" to check out branch tip)"); // } - if (shouldPull()) { - boolean pullResult = pull(repoRoot, indicator); - if (!pullResult) { - return false; - } + HgRevisionNumber parentBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot); + int pullResult = pull(repoRoot, indicator, shouldRebase()); + if (pullResult == HgPullCommand.ERROR) { + return false; } - if (shouldUpdate()) { + HgRevisionNumber paretnAfterUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot); - List parentsBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).parents(repoRoot); - if (parentsBeforeUpdate.size() > 1) { - throw new VcsException(HgVcsMessages.message("hg4idea.update.error.uncommittedMerge", repoRoot.getPath())); - } + if (pullResult == HgPullCommand.SUCCESS) { + addUpdatedFiles(repoRoot, updatedFiles, parentBeforeUpdate, paretnAfterUpdate); + return true; + } + + if (shouldMerge()) { indicator.setText2(HgVcsMessages.message("hg4idea.progress.countingHeads")); List branchHeadsAfterPull = new HgHeadsCommand(project, repoRoot).execute(); List pulledBranchHeads = determinePulledBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull); - List remainingOriginalBranchHeads = determingRemainingOriginalBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull); + List remainingOriginalBranchHeads = + determingRemainingOriginalBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull); - if (branchHeadsAfterPull.size() > 1 && shouldMerge()) { + if (branchHeadsAfterPull.size() > 1) { abortOnLocalChanges(); abortOnMultiplePulledHeads(pulledBranchHeads); abortOnMultipleLocalHeads(remainingOriginalBranchHeads); @@ -118,14 +118,14 @@ public class HgRegularUpdater implements HgUpdater { if (shouldCommitAfterMerge()) { commitOrWarnAboutConflicts(warnings, mergeResult); } - } else { - //in case of multiple heads the update will report the appropriate error - update(repoRoot, indicator, updatedFiles, warnings); } - //any kind of update could have resulted in merges and merge conflicts, so run the resolver resolvePossibleConflicts(updatedFiles); } + else { + processRebase(updatedFiles); + } + return true; } @@ -207,6 +207,24 @@ public class HgRegularUpdater implements HgUpdater { return new HgHeadMerger(project, mergeCommand).merge(repoRoot); } + private void processRebase(final UpdatedFiles updatedFiles) throws VcsException { + + HgCommandResult result; + do { + resolvePossibleConflicts(updatedFiles); + if (!HgConflictResolver.findConflicts(project, updatedFiles, repoRoot).isEmpty()) { + return; + } + HgRebaseCommand rebaseCommand = new HgRebaseCommand(project, repoRoot); + result = rebaseCommand.continueRebase(); + if (HgErrorUtil.isAbort(result)) { + new HgCommandResultNotifier(project).notifyError(result, "Hg Error", "Couldn't continue rebasing"); + return; + } + } + while (result.getExitValue() == 1); + } + private void abortOnLocalChanges() throws VcsException { if (getLocalChanges().size() != 0) { throw new VcsException(HgVcsMessages.message("hg4idea.update.error.localchanges", repoRoot.getPath())); @@ -222,14 +240,18 @@ public class HgRegularUpdater implements HgUpdater { return statusCommand.execute(repoRoot); } - private boolean pull(VirtualFile repo, ProgressIndicator indicator) + private int pull(VirtualFile repo, ProgressIndicator indicator, boolean isRebase) throws VcsException { indicator.setText2(HgVcsMessages.message("hg4idea.progress.pull.with.update")); HgPullCommand hgPullCommand = new HgPullCommand(project, repo); final String defaultPath = HgUtil.getRepositoryDefaultPath(project, repo); hgPullCommand.setSource(defaultPath); - hgPullCommand.setUpdate(false); - hgPullCommand.setRebase(false); + if (isRebase) { + hgPullCommand.setRebase(true); + } + else { + hgPullCommand.setUpdate(true); + } return hgPullCommand.execute(); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdater.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdater.java index a724f4501acb..c0897f153834 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdater.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdater.java @@ -23,19 +23,11 @@ public interface HgUpdater { boolean update(UpdatedFiles updatedFiles, ProgressIndicator indicator, List exceptions) throws VcsException; - static class UpdateConfiguration{ - private boolean shouldPull = true; - private boolean shouldUpdate = true; + class UpdateConfiguration{ private boolean shouldMerge = true; private boolean shouldCommitAfterMerge = true; + private boolean shouldRebase = true; - public void setShouldPull(boolean shouldPull) { - this.shouldPull = shouldPull; - } - - public void setShouldUpdate(boolean shouldUpdate) { - this.shouldUpdate = shouldUpdate; - } public void setShouldMerge(boolean shouldMerge) { this.shouldMerge = shouldMerge; @@ -45,16 +37,16 @@ public interface HgUpdater { this.shouldCommitAfterMerge = shouldCommitAfterMerge; } - public boolean shouldPull() { - return shouldPull; - } - - public boolean shouldUpdate() { - return shouldUpdate; + public void setShouldRebase(boolean shouldRebase) { + this.shouldRebase = shouldRebase; + } + + public boolean shouldRebase() { + return shouldRebase; } public boolean shouldMerge() { - return shouldUpdate() && shouldMerge; + return shouldMerge; } public boolean shouldCommitAfterMerge() { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java index d6ee73922a71..7c97f07fbfbe 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryFiles.java @@ -34,6 +34,7 @@ public class HgRepositoryFiles { // so check for starting branch public static final String BRANCHEADSDIR = "cache"; public static final String MERGE = "merge"; + public static final String REBASE = "rebase"; //rebasestate public static final String BRANCH = "branch"; public static final String BOOKMARKS = "bookmarks"; public static final String LOCAL_TAGS = "localtags"; @@ -45,6 +46,7 @@ public class HgRepositoryFiles { @NotNull private final String myBranchHeadsPath; @NotNull private final String myBranchHeadsDirPath; @NotNull private final String myMergePath; + @NotNull private final String myRebasePath; @NotNull private final String myBranchPath; @NotNull private final String myBookmarksPath; @NotNull private final String myTagsPath; @@ -62,6 +64,7 @@ public class HgRepositoryFiles { myBranchHeadsDirPath = hgDir.getPath() + slash(BRANCHEADSDIR); myBranchPath = hgDir.getPath() + slash(BRANCH); myMergePath = hgDir.getPath() + slash(MERGE); + myRebasePath = hgDir.getPath() + slash(REBASE); myBookmarksPath = hgDir.getPath() + slash(BOOKMARKS); myTagsPath = hgDir.getParent().getPath() + slash(TAGS); myLocalTagsPath = hgDir.getPath() + slash(LOCAL_TAGS); @@ -99,6 +102,10 @@ public class HgRepositoryFiles { return filePath.startsWith(myMergePath); } + public boolean isRebaseFile(String filePath) { + return filePath.startsWith(myRebasePath); + } + public boolean isBookmarksFile(String filePath) { return filePath.equals(myBookmarksPath); } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java index e35d7892d331..bfec1db1573b 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java @@ -142,8 +142,15 @@ public class HgRepositoryReader { return new File(myHgDir, "merge").exists(); } + public boolean isRebaseInProgress() { + return new File(myHgDir, "rebasestate").exists(); + } + @NotNull public Repository.State readState() { + if (isRebaseInProgress()) { + return Repository.State.REBASING; + } return isMergeInProgress() ? Repository.State.MERGING : Repository.State.NORMAL; } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java index 1b53bdcd5e58..39a3106b8761 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryUpdater.java @@ -91,6 +91,7 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener { boolean branchHeadsChanged = false; boolean branchFileChanged = false; boolean mergeFileChanged = false; + boolean rebaseFileChanged = false; boolean bookmarksFileChanged = false; boolean tagsFileChanged = false; boolean localTagsFileChanged = false; @@ -111,6 +112,9 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener { else if (myRepositoryFiles.isMergeFile(filePath)) { mergeFileChanged = true; } + else if (myRepositoryFiles.isRebaseFile(filePath)) { + rebaseFileChanged = true; + } else if (myRepositoryFiles.isBookmarksFile(filePath)) { bookmarksFileChanged = true; } @@ -132,6 +136,7 @@ final class HgRepositoryUpdater implements Disposable, BulkFileListener { if (branchHeadsChanged || branchFileChanged || mergeFileChanged || + rebaseFileChanged || bookmarksFileChanged || currentBookmarkFileChanged || tagsFileChanged || diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.form deleted file mode 100644 index 34b0d83022ba..000000000000 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.form +++ /dev/null @@ -1,59 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java index 168954e1cddd..de4b865e5ca7 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgUpdateDialog.java @@ -12,6 +12,8 @@ // limitations under the License. package org.zmlx.hg4idea.ui; +import com.intellij.ui.IdeBorderFactory; +import net.miginfocom.swing.MigLayout; import org.zmlx.hg4idea.provider.update.HgUpdater; import javax.swing.*; @@ -22,45 +24,62 @@ import java.awt.event.ItemListener; * Configuration dialog for the update process. */ public class HgUpdateDialog { - private JPanel contentPane; - private JCheckBox pullCheckBox; - private JCheckBox updateCheckBox; - private JCheckBox mergeCheckBox; - private JCheckBox commitAfterMergeCheckBox; + private JCheckBox myCommitAfterMergeCheckBox; + private JRadioButton myMergeRadioButton; + private JRadioButton myRebaseRadioButton; + public HgUpdateDialog() { - ItemListener enabledListener = new ItemListener() { - public void itemStateChanged(ItemEvent e) { - updateEnabledStates(); - } - }; - updateCheckBox.addItemListener(enabledListener); - mergeCheckBox.addItemListener(enabledListener); - updateEnabledStates(); + createCenterPanel(); } private void updateEnabledStates() { - //TODO this information is actually duplicated in the HgRegularUpdater (as a series of nested ifs) - mergeCheckBox.setEnabled(updateCheckBox.isSelected()); - commitAfterMergeCheckBox.setEnabled(mergeCheckBox.isEnabled() && mergeCheckBox.isSelected()); + myCommitAfterMergeCheckBox.setEnabled(myMergeRadioButton.isSelected()); } public void applyTo(HgUpdater.UpdateConfiguration updateConfiguration) { - updateConfiguration.setShouldPull(pullCheckBox.isSelected()); - updateConfiguration.setShouldUpdate(updateCheckBox.isSelected()); - updateConfiguration.setShouldMerge(mergeCheckBox.isSelected()); - updateConfiguration.setShouldCommitAfterMerge(commitAfterMergeCheckBox.isSelected()); + updateConfiguration.setShouldMerge(myMergeRadioButton.isSelected()); + updateConfiguration.setShouldCommitAfterMerge(myCommitAfterMergeCheckBox.isSelected()); + updateConfiguration.setShouldRebase(myRebaseRadioButton.isSelected()); } public JComponent createCenterPanel() { + MigLayout migLayout = new MigLayout("flowy,ins 0, fill"); + JPanel contentPane = new JPanel(migLayout); + + + + contentPane.setBorder(IdeBorderFactory.createTitledBorder("Update Type")); + + myMergeRadioButton = new JRadioButton("Merge", true); + myMergeRadioButton.setMnemonic('m'); + myMergeRadioButton.setToolTipText("Merge if pulling resulted in extra heads"); + myCommitAfterMergeCheckBox = new JCheckBox("Commit after merge without conflicts", false); + myCommitAfterMergeCheckBox.setMnemonic('c'); + myCommitAfterMergeCheckBox.setToolTipText("Commit automatically after the merge"); + myRebaseRadioButton = new JRadioButton("Rebase", false); + myRebaseRadioButton.setToolTipText("Rebase changesets to a branch tip as destination"); + myRebaseRadioButton.setMnemonic('r'); + final ButtonGroup radioButtonGroup = new ButtonGroup(); + radioButtonGroup.add(myMergeRadioButton); + radioButtonGroup.add(myRebaseRadioButton); + + contentPane.add(myMergeRadioButton, "left"); + contentPane.add(myCommitAfterMergeCheckBox, "gapx 5%"); + contentPane.add(myRebaseRadioButton, "left"); + myMergeRadioButton.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateEnabledStates(); + } + }); + + updateEnabledStates(); return contentPane; } public void updateFrom(HgUpdater.UpdateConfiguration updateConfiguration) { - pullCheckBox.setSelected(updateConfiguration.shouldPull()); - updateCheckBox.setSelected(updateConfiguration.shouldUpdate()); - mergeCheckBox.setSelected(updateConfiguration.shouldMerge()); - commitAfterMergeCheckBox.setSelected(updateConfiguration.shouldCommitAfterMerge()); + myMergeRadioButton.setSelected(updateConfiguration.shouldMerge()); + myCommitAfterMergeCheckBox.setSelected(updateConfiguration.shouldCommitAfterMerge()); + myRebaseRadioButton.setSelected(updateConfiguration.shouldRebase()); } - } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java index ee7f1b4f5ce4..ad28fd7a9936 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java @@ -571,7 +571,7 @@ public abstract class HgUtil { public static String getDisplayableBranchOrBookmarkText(@NotNull HgRepository repository) { HgRepository.State state = repository.getState(); String branchText = ""; - if (state == HgRepository.State.MERGING) { + if (state != HgRepository.State.NORMAL) { branchText += state.toString() + " "; } String branchOrBookMarkName = repository.getCurrentBookmark(); diff --git a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgUpdateTest.java b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgUpdateTest.java index 8ab8cd367763..456ad4aac580 100644 --- a/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgUpdateTest.java +++ b/plugins/hg4idea/testSrc/org/zmlx/hg4idea/test/HgUpdateTest.java @@ -60,7 +60,6 @@ public class HgUpdateTest extends HgCollaborativeTest { //do a simple pull without an update HgPullCommand pull = new HgPullCommand(myProject, projectRepoVirtualFile); pull.setSource(HgUtil.getRepositoryDefaultPath(myProject, projectRepoVirtualFile)); - pull.setUpdate(false); pull.execute(); assertEquals( determineNumberOfIncomingChanges( projectRepo ), 0,