@Override public <S> List<S> filterUniqueRoots( final List<S> in, final Convertor<S, VirtualFile> convertor) { Collections.sort( in, new ComparatorDelegate<S, VirtualFile>(convertor, FilePathComparator.getInstance())); for (int i = 1; i < in.size(); i++) { final S sChild = in.get(i); final VirtualFile child = convertor.convert(sChild); final VirtualFile childRoot = HgUtil.getHgRootOrNull(myProject, child); if (childRoot == null) { continue; } for (int j = i - 1; j >= 0; --j) { final S sParent = in.get(j); final VirtualFile parent = convertor.convert(sParent); // if the parent is an ancestor of the child and that they share common root, the child is // removed if (VfsUtil.isAncestor(parent, child, false) && VfsUtil.isAncestor(childRoot, parent, false)) { in.remove(i); //noinspection AssignmentToForLoopParameter --i; break; } } } return in; }
@Test public void updateKeepsWorkingAfterPull() throws Exception { changeFile_A_AndCommitInRemoteRepository(); // 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, "The update operation should have pulled the incoming changes from the default repository."); updateThroughPlugin(); HgRevisionNumber parentRevision = new HgWorkingCopyRevisionsCommand(myProject).firstParent(projectRepoVirtualFile); assertEquals( parentRevision.getRevision(), "1", "The working directory should have been updated to the latest version"); }
@Override public void conflictResolvedForFile(VirtualFile file) { try { new HgResolveCommand(myProject).markResolved(HgUtil.getHgRootOrThrow(myProject, file), file); } catch (VcsException e) { LOG.error("Couldn't mark file resolved, because it is not under Mercurial root."); } }
@Nullable @Override protected HgRepository guessCurrentRepository(@NotNull Project project) { return DvcsUtil.guessCurrentRepositoryQuick( project, HgUtil.getRepositoryManager(project), HgProjectSettings.getInstance(project).getRecentRootPath()); }
public static HgFile getOriginalHgFile(Project project, VirtualFile root) { HgFile hgFile = new HgFile(root, VcsUtil.getFilePath(root.getPath())); if (project.isDisposed()) { return hgFile; } FilePath originalFileName = HgUtil.getOriginalFileName(hgFile.toFilePath(), ChangeListManager.getInstance(project)); return new HgFile(hgFile.getRepo(), originalFileName); }
/** * @return the prompthooks.py extension used for capturing prompts from Mercurial and requesting * IDEA's user about authentication. */ @NotNull public File getPromptHooksExtensionFile() { if (myPromptHooksExtensionFile == null) { // check that hooks are available myPromptHooksExtensionFile = HgUtil.getTemporaryPythonFile("prompthooks"); if (myPromptHooksExtensionFile == null || !myPromptHooksExtensionFile.exists()) { LOG.error( "prompthooks.py Mercurial extension is not found. Please reinstall " + ApplicationNamesInfo.getInstance().getProductName()); } } return myPromptHooksExtensionFile; }
private HgCommandExitCode 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); if (isRebase) { hgPullCommand.setRebase(true); } else { hgPullCommand.setUpdate(true); } return hgPullCommand.execute(); }
private void processRebase(final UpdatedFiles updatedFiles) throws VcsException { HgRepository repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(repoRoot); HgCommandResult result; do { resolvePossibleConflicts(updatedFiles); if (repository == null || !HgConflictResolver.findConflicts(project, repoRoot).isEmpty()) { return; } HgRebaseCommand rebaseCommand = new HgRebaseCommand(project, repository); result = rebaseCommand.continueRebase(); if (HgErrorUtil.isAbort(result)) { new HgCommandResultNotifier(project) .notifyError(result, "Hg Error", "Couldn't continue rebasing"); return; } } while (result.getExitValue() == 1); }
public void showDialogAndPush(@Nullable final VirtualFile selectedRepo) { HgUtil.executeOnPooledThreadIfNeeded( new Runnable() { public void run() { final List<VirtualFile> repositories = HgUtil.getHgRepositories(myProject); if (repositories.isEmpty()) { VcsBalloonProblemNotifier.showOverChangesView( myProject, "No Mercurial repositories in the project", MessageType.ERROR); return; } VirtualFile firstRepo = repositories.get(0); final List<HgTagBranch> branches = getBranches(myProject, firstRepo); if (branches.isEmpty()) { return; } final AtomicReference<HgPushCommand> pushCommand = new AtomicReference<HgPushCommand>(); UIUtil.invokeAndWaitIfNeeded( new Runnable() { @Override public void run() { final HgPushDialog dialog = new HgPushDialog(myProject, repositories, branches, selectedRepo); dialog.show(); if (dialog.isOK()) { dialog.rememberSettings(); pushCommand.set(preparePushCommand(myProject, dialog)); } } }); if (pushCommand.get() != null) { push(myProject, pushCommand.get()); } } }); }
@Override public void activate() { super.activate(); // validate hg executable on start if (!ApplicationManager.getApplication().isUnitTestMode()) { getExecutableValidator().checkExecutableAndNotifyIfNeeded(); } // status bar myStatusWidget = new HgStatusWidget(this, getProject(), projectSettings); myStatusWidget.activate(); myIncomingWidget = new HgIncomingOutgoingWidget(this, getProject(), projectSettings, true); myIncomingWidget.activate(); myOutgoingWidget = new HgIncomingOutgoingWidget(this, getProject(), projectSettings, false); myOutgoingWidget.activate(); // updaters and listeners myHgRemoteStatusUpdater = new HgRemoteStatusUpdater( this, myIncomingWidget.getChangesetStatus(), myOutgoingWidget.getChangesetStatus(), projectSettings); myHgRemoteStatusUpdater.activate(); myHgCurrentBranchStatusUpdater = new HgCurrentBranchStatusUpdater(this, myStatusWidget.getCurrentBranchStatus()); myHgCurrentBranchStatusUpdater.activate(); messageBusConnection = myProject.getMessageBus().connect(); messageBusConnection.subscribe( FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() { @Override public void selectionChanged(FileEditorManagerEvent event) { Project project = event.getManager().getProject(); project.getMessageBus().syncPublisher(BRANCH_TOPIC).update(project, null); } }); myVFSListener = new HgVFSListener(myProject, this); // ignore temporary files final String ignoredPattern = FileTypeManager.getInstance().getIgnoredFilesList(); if (!ignoredPattern.contains(ORIG_FILE_PATTERN)) { final String newPattern = ignoredPattern + (ignoredPattern.endsWith(";") ? "" : ";") + ORIG_FILE_PATTERN; HgUtil.runWriteActionLater( new Runnable() { public void run() { FileTypeManager.getInstance().setIgnoredFilesList(newPattern); } }); } // Force a branch topic update myProject.getMessageBus().syncPublisher(BRANCH_TOPIC).update(myProject, null); }
@Override public boolean isVersionedDirectory(VirtualFile dir) { return HgUtil.getNearestHgRoot(dir) != null; }
@Override protected boolean isMultiRoot(@NotNull Project project) { return HgUtil.getRepositoryManager(project).moreThanOneRoot(); }
@NotNull @Override protected String getFullBranchName(@NotNull HgRepository repository) { return HgUtil.getDisplayableBranchOrBookmarkText(repository); }
public boolean update( final UpdatedFiles updatedFiles, ProgressIndicator indicator, List<VcsException> warnings) throws VcsException { indicator.setText(HgVcsMessages.message("hg4idea.progress.updating", repoRoot.getPath())); String defaultPath = HgUtil.getRepositoryDefaultPath(project, repoRoot); if (StringUtil.isEmptyOrSpaces(defaultPath)) { throw new VcsException( HgVcsMessages.message("hg4idea.warning.no-default-update-path", repoRoot.getPath())); } List<HgRevisionNumber> branchHeadsBeforePull = new HgHeadsCommand(project, repoRoot).execute(); if (branchHeadsBeforePull.size() > 1) { reportWarning( warnings, HgVcsMessages.message( "hg4idea.update.warning.multipleHeadsBeforeUpdate", repoRoot.getPath())); } // TODO perhaps report a warning in this case ? // //if the parent of the working dir is not the tip of the current branch, the user has // //manually brought his working copy to some specific revision. In that case we won't touch // //his setup // if (!parentRevision.equals(currentBranchHead)) { // throw new VcsException("working dir not at branch tip (use \"Update to...\" to check out // branch tip)"); // } HgRevisionNumber parentBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot); HgCommandExitCode pullResult = pull(repoRoot, indicator, shouldRebase()); if (pullResult == HgCommandExitCode.ERROR) { return false; } if (pullResult == HgCommandExitCode.SUCCESS) { HgRevisionNumber parentAfterUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot); addUpdatedFiles(repoRoot, updatedFiles, parentBeforeUpdate, parentAfterUpdate); 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); if (branchHeadsAfterPull.size() > 1) { abortOnLocalChanges(); abortOnMultiplePulledHeads(pulledBranchHeads); abortOnMultipleLocalHeads(remainingOriginalBranchHeads); HgCommandResult mergeResult = doMerge(indicator); if (shouldCommitAfterMerge()) { commitOrWarnAboutConflicts(warnings, mergeResult); } } // any kind of update could have resulted in merges and merge conflicts, so run the resolver resolvePossibleConflicts(updatedFiles); } else { processRebase(updatedFiles); } return true; }