mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
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
This commit is contained in:
@@ -77,6 +77,9 @@
|
||||
<action id="hg4idea.tag" class="org.zmlx.hg4idea.action.HgCreateTagAction"/>
|
||||
<action id="hg4idea.updateTo" class="org.zmlx.hg4idea.action.HgUpdateToAction"/>
|
||||
<action id="hg4idea.resolve.mark" class="org.zmlx.hg4idea.action.HgMarkResolved"/>
|
||||
<separator/>
|
||||
<action id="hg4idea.Rebase.Abort" class="org.zmlx.hg4idea.action.HgAbortRebaseAction" text="Abort Rebasing"/>
|
||||
<action id="hg4idea.Rebase.Continue" class="org.zmlx.hg4idea.action.HgContinueRebaseAction" text="Continue Rebasing"/>
|
||||
|
||||
<separator/>
|
||||
<reference id="ChangesView.Browse"/>
|
||||
|
||||
@@ -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<HgRepository> 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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<HgRepository> 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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -51,8 +51,6 @@ public class HgPullAction extends HgAbstractGlobalAction {
|
||||
project, dialog.getRepository()
|
||||
);
|
||||
command.setSource(dialog.getSource());
|
||||
command.setRebase(false);
|
||||
command.setUpdate(false);
|
||||
|
||||
command.execute();
|
||||
}
|
||||
|
||||
@@ -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<String> arguments = new LinkedList<String>();
|
||||
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 <code>" + source + "</code>");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,25 @@ public final class HgConflictResolver {
|
||||
}
|
||||
|
||||
public void resolve(final VirtualFile repo) {
|
||||
Map<HgFile, HgResolveStatusEnum> resolves = new HgResolveCommand(myProject).getListSynchronously(repo);
|
||||
final List<VirtualFile> 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<VirtualFile> findConflicts(final Project project, final UpdatedFiles updatedFiles, VirtualFile repo) {
|
||||
Map<HgFile, HgResolveStatusEnum> resolves = new HgResolveCommand(project).getListSynchronously(repo);
|
||||
final List<VirtualFile> conflicts = new ArrayList<VirtualFile>();
|
||||
for (Map.Entry<HgFile, HgResolveStatusEnum> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<HgRevisionNumber> 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<HgRevisionNumber> branchHeadsAfterPull = new HgHeadsCommand(project, repoRoot).execute();
|
||||
List<HgRevisionNumber> pulledBranchHeads = determinePulledBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);
|
||||
List<HgRevisionNumber> remainingOriginalBranchHeads = determingRemainingOriginalBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);
|
||||
List<HgRevisionNumber> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,19 +23,11 @@ public interface HgUpdater {
|
||||
boolean update(UpdatedFiles updatedFiles, ProgressIndicator indicator, List<VcsException> 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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgUpdateDialog">
|
||||
<grid id="27dc6" binding="contentPane" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="6a810" class="javax.swing.JCheckBox" binding="pullCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&pull"/>
|
||||
<toolTipText value="pull from the default remote repository"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="732d8">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<component id="2555e" class="javax.swing.JCheckBox" binding="updateCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&update"/>
|
||||
<toolTipText value="update to the head of the current branch"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="3a607" class="javax.swing.JCheckBox" binding="mergeCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&merge"/>
|
||||
<toolTipText value="merge if pulling resulted in extra heads"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6499c" class="javax.swing.JCheckBox" binding="commitAfterMergeCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&commit after merge without conflicts"/>
|
||||
<toolTipText value="commit automatically after the merge"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="26be6">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user