@NotNull public static <CommitInfo> List<CommitInfo> getCommitRecords( @NotNull Project project, @Nullable HgCommandResult result, @NotNull Function<String, CommitInfo> converter, boolean silent) { final List<CommitInfo> revisions = new LinkedList<CommitInfo>(); if (result == null) { return revisions; } List<String> errors = result.getErrorLines(); if (errors != null && !errors.isEmpty()) { if (result.getExitValue() != 0) { if (silent) { LOG.warn(errors.toString()); } else { VcsNotifier.getInstance(project) .notifyError( HgVcsMessages.message("hg4idea.error.log.command.execution"), errors.toString()); } return Collections.emptyList(); } LOG.warn(errors.toString()); } String output = result.getRawOutput(); List<String> changeSets = StringUtil.split(output, HgChangesetUtil.CHANGESET_SEPARATOR); return ContainerUtil.mapNotNull(changeSets, converter); }
private HgCommandResult doMerge(ProgressIndicator indicator) throws VcsException { indicator.setText2(HgVcsMessages.message("hg4idea.update.progress.merging")); HgMergeCommand mergeCommand = new HgMergeCommand(project, repoRoot); // do not explicitly set the revision, that way mercurial itself checks that there are exactly // two heads in this branch // mergeCommand.setRevision(headToMerge.getRevision()); return new HgHeadMerger(project, mergeCommand).merge(repoRoot); }
private void abortOnMultipleLocalHeads(List<HgRevisionNumber> originalBranchHeadsRemaining) throws VcsException { if (originalBranchHeadsRemaining.size() != 1) { throw new VcsException( HgVcsMessages.message( "hg4idea.update.error.merge.multipleLocalHeads", repoRoot.getPath())); } }
private void abortOnMultiplePulledHeads(List<HgRevisionNumber> newBranchHeadsAfterPull) throws VcsException { if (newBranchHeadsAfterPull.size() != 1) { throw new VcsException( HgVcsMessages.message( "hg4idea.update.error.merge.multipleRemoteHeads", newBranchHeadsAfterPull.size(), repoRoot.getPath())); } }
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(); }
@NotNull public static List<HgTagBranch> getBranches(@NotNull Project project, @NotNull VirtualFile root) { HgCommandResult branchesResult = new HgTagBranchCommand(project, root).collectBranches(); if (branchesResult == null) { new HgCommandResultNotifier(project) .notifyError( branchesResult, "Mercurial command failed", HgVcsMessages.message("hg4idea.branches.error.description")); return Collections.emptyList(); } return HgTagBranchCommand.parseResult(branchesResult); }
public HgExecutableValidator(Project project) { super(project, HgVcs.NOTIFICATION_GROUP_ID); myVcs = HgVcs.getInstance(project); setMessagesAndTitles( HgVcsMessages.message("hg4idea.executable.notification.title"), HgVcsMessages.message("hg4idea.executable.notification.description"), HgVcsMessages.message("hg4idea.executable.dialog.title"), HgVcsMessages.message("hg4idea.executable.dialog.description"), HgVcsMessages.message("hg4idea.executable.dialog.error"), HgVcsMessages.message("hg4idea.executable.filechooser.title"), HgVcsMessages.message("hg4idea.executable.filechooser.description")); }
private void commitOrWarnAboutConflicts( List<VcsException> exceptions, HgCommandResult mergeResult) throws VcsException { if (mergeResult.getExitValue() == 0) { // operation successful and no conflicts try { new HgCommitCommand(project, repoRoot, "Automated merge").execute(); } catch (HgCommandException e) { throw new VcsException(e); } } else { reportWarning( exceptions, HgVcsMessages.message("hg4idea.update.warning.merge.conflicts", repoRoot.getPath())); } }
public class HgProjectConfigurable implements SearchableConfigurable { public static final String DISPLAY_NAME = HgVcsMessages.message("hg4idea.mercurial"); private final HgConfigurationProjectPanel myPanel; @NotNull private final Project myProject; public HgProjectConfigurable(@NotNull Project project, HgProjectSettings projectSettings) { myProject = project; myPanel = new HgConfigurationProjectPanel(projectSettings, myProject); } @Nls public String getDisplayName() { return DISPLAY_NAME; } public String getHelpTopic() { return "project.propVCSSupport.VCSs.Mercurial"; } public JComponent createComponent() { return myPanel.getPanel(); } public boolean isModified() { return myPanel.isModified(); } public void apply() throws ConfigurationException { myPanel.saveSettings(); if (myPanel.getProjectSettings().isCheckIncomingOutgoing()) { myProject.getMessageBus().syncPublisher(HgVcs.INCOMING_OUTGOING_CHECK_TOPIC).show(); } else { myProject.getMessageBus().syncPublisher(HgVcs.INCOMING_OUTGOING_CHECK_TOPIC).hide(); } } public void reset() { myPanel.loadSettings(); } public void disposeUIResources() {} @NotNull public String getId() { return "Mercurial.Project"; } }
private void updateToPulledHead( VirtualFile repo, UpdatedFiles updatedFiles, HgRevisionNumber newHead, ProgressIndicator indicator) { indicator.setText2(HgVcsMessages.message("hg4idea.update.progress.updating.to.pulled.head")); HgRevisionNumber parentBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repo); HgUpdateCommand updateCommand = new HgUpdateCommand(project, repoRoot); updateCommand.setRevision(newHead.getChangeset()); updateCommand.setClean(true); updateCommand.execute(); HgRevisionNumber commonParent = findCommonParent(newHead, parentBeforeUpdate); addUpdatedFiles(repo, updatedFiles, commonParent, newHead); }
private void update( @NotNull VirtualFile repo, ProgressIndicator indicator, UpdatedFiles updatedFiles, List<VcsException> warnings) throws VcsException { indicator.setText2(HgVcsMessages.message("hg4idea.progress.updatingworkingdir")); HgRevisionNumber parentBeforeUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repo); HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(project, repo); String warningMessages = ensureSuccess(hgUpdateCommand.execute()).getWarnings(); handlePossibleWarning(warnings, warningMessages); HgRevisionNumber parentAfterUpdate = new HgWorkingCopyRevisionsCommand(project).firstParent(repo); addUpdatedFiles(repo, updatedFiles, parentBeforeUpdate, parentAfterUpdate); }
public String getDisplayName() { return HgVcsMessages.message("hg4idea.mercurial"); }
/** * Checks Hg version and updates the myVersion variable. In the case of nullable or unsupported * version reports the problem. */ public void checkVersion() { final String executable = getGlobalSettings().getHgExecutable(); HgCommandResultNotifier errorNotification = new HgCommandResultNotifier(myProject); final String SETTINGS_LINK = "settings"; final String UPDATE_LINK = "update"; NotificationListener linkAdapter = new NotificationListener.Adapter() { @Override protected void hyperlinkActivated( @NotNull Notification notification, @NotNull HyperlinkEvent e) { if (SETTINGS_LINK.equals(e.getDescription())) { ShowSettingsUtil.getInstance() .showSettingsDialog(myProject, getConfigurable().getDisplayName()); } else if (UPDATE_LINK.equals(e.getDescription())) { BrowserUtil.browse("http://mercurial.selenic.com"); } } }; try { myVersion = HgVersion.identifyVersion(executable); // if version is not supported, but have valid hg executable if (!myVersion.isSupported()) { LOG.info("Unsupported Hg version: " + myVersion); String message = String.format( "The <a href='" + SETTINGS_LINK + "'>configured</a> version of Hg is not supported: %s.<br/> " + "The minimal supported version is %s. Please <a href='" + UPDATE_LINK + "'>update</a>.", myVersion, HgVersion.MIN); errorNotification.notifyError(null, "Unsupported Hg version", message, linkAdapter); } else if (myVersion.hasUnsupportedExtensions()) { String unsupportedExtensionsAsString = myVersion.getUnsupportedExtensions().toString(); LOG.warn("Unsupported Hg extensions: " + unsupportedExtensionsAsString); String message = String.format( "Some hg extensions %s are not found or not supported by your hg version and will be ignored.\n" + "Please, update your hgrc or Mercurial.ini file", unsupportedExtensionsAsString); errorNotification.notifyWarning("Unsupported Hg version", message); } } catch (Exception e) { if (getExecutableValidator().checkExecutableAndNotifyIfNeeded()) { // sometimes not hg application has version command, but we couldn't parse an answer as // valid hg, // so parse(output) throw ParseException, but hg and git executable seems to be valid in // this case final String reason = (e.getCause() != null ? e.getCause() : e).getMessage(); String message = HgVcsMessages.message("hg4idea.unable.to.run.hg", executable); errorNotification.notifyError( null, message, String.format( reason + "<br/> Please check your hg executable path in <a href='" + SETTINGS_LINK + "'> settings </a>"), linkAdapter); } } }
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; }
private void abortOnLocalChanges() throws VcsException { if (getLocalChanges().size() != 0) { throw new VcsException( HgVcsMessages.message("hg4idea.update.error.localchanges", repoRoot.getPath())); } }