Search in sources :

Example 11 with HgCommandResult

use of org.zmlx.hg4idea.execution.HgCommandResult in project intellij-community by JetBrains.

the class HgMergeProvider method loadRevisions.

@NotNull
@Override
public MergeData loadRevisions(@NotNull final VirtualFile file) throws VcsException {
    final MergeData mergeData = new MergeData();
    final VcsRunnable runnable = new VcsRunnable() {

        @Override
        public void run() throws VcsException {
            final HgWorkingCopyRevisionsCommand command = new HgWorkingCopyRevisionsCommand(myProject);
            final VirtualFile repo = HgUtil.getHgRootOrThrow(myProject, file);
            final HgFile hgFile = new HgFile(myProject, file);
            HgRevisionNumber serverRevisionNumber;
            HgRevisionNumber localRevisionNumber;
            HgRevisionNumber baseRevisionNumber = null;
            // there are two possibilities: we have checked in local changes in the selected file or we didn't.
            if (wasFileCheckedIn(repo, file)) {
                // 1. We checked in.
                // We have a merge in progress, which means we have 2 heads (parents).
                // the second one is "their" revision pulled from the parent repo,
                // first parent is the local change.
                // to retrieve the base version we get the parent of the local change, i.e. the [only] parent of the first parent.
                //Which one is local revision depends on which one is merged with,
                // i.e if you update to 17 revision and then merge it with 23, so 17 is your local and 17->parent is your base revision.
                // This may produce misunderstanding when you update your project with merging (your update firstly to next revisions  and then
                // merge with previous). see http://hgbook.red-bean.com/read/managing-releases-and-branchy-development.html
                final Couple<HgRevisionNumber> parents = command.parents(repo, file);
                serverRevisionNumber = parents.second;
                localRevisionNumber = parents.first;
                final HgContentRevision local = HgContentRevision.create(myProject, hgFile, localRevisionNumber);
                mergeData.CURRENT = local.getContentAsBytes();
                // we are sure that we have a common ancestor, because otherwise we'll get "repository is unrelated" error while pulling,
                // due to different root changesets which is prohibited.
                // Find common ancestor of two revisions : hg debugancestor rev1 rev2
                // Using quotes may produce wrong escaping errors on Unix-type systems
                List<String> arguments = new ArrayList<>();
                String localChangeset = localRevisionNumber.getChangeset();
                String serverChangeset = serverRevisionNumber.getChangeset();
                arguments.add(StringUtil.isEmptyOrSpaces(localChangeset) ? localRevisionNumber.getRevision() : localChangeset);
                arguments.add(StringUtil.isEmptyOrSpaces(serverChangeset) ? serverRevisionNumber.getRevision() : serverChangeset);
                HgCommandResult result = new HgPromptCommandExecutor(myProject).executeInCurrentThread(repo, "debugancestor", arguments);
                if (result != null) {
                    String output = result.getRawOutput();
                    final List<String> parts = StringUtil.split(output, ":");
                    if (parts.size() < 2) {
                        LOG.info("Couldn't parse result of debugancestor command execution " + arguments);
                        new HgCommandResultNotifier(myProject).notifyError(null, HgVcsMessages.message("hg4idea.error.debugancestor.command.execution"), HgVcsMessages.message("hg4idea.error.debugancestor.command.description"));
                    } else {
                        baseRevisionNumber = HgRevisionNumber.getInstance(parts.get(0), parts.get(1));
                    }
                } else {
                    LOG.info(HgVcsMessages.message("hg4idea.error.debugancestor.command.execution") + arguments);
                    new HgCommandResultNotifier(myProject).notifyError(null, HgVcsMessages.message("hg4idea.error.debugancestor.command.execution"), HgVcsMessages.message("hg4idea.error.debugancestor.command.description"));
                }
            } else {
                // 2. local changes are not checked in.
                // then there is only one parent, which is server changes.
                // local changes are retrieved from the file system, they are not in the Mercurial yet.
                // base is the only parent of server changes.
                serverRevisionNumber = command.parents(repo, file).first;
                baseRevisionNumber = command.parents(repo, file, serverRevisionNumber).first;
                final File origFile = new File(file.getPath() + ".orig");
                mergeData.CURRENT = VcsUtil.getFileByteContent(origFile);
            }
            if (baseRevisionNumber != null) {
                final HgContentRevision base = HgContentRevision.create(myProject, hgFile, baseRevisionNumber);
                //if file doesn't exist in ancestor revision the base revision should be empty
                mergeData.ORIGINAL = base.getContent() != null ? base.getContentAsBytes() : ArrayUtil.EMPTY_BYTE_ARRAY;
            } else {
                // no base revision means that the file was added simultaneously with different content in both repositories
                mergeData.ORIGINAL = ArrayUtil.EMPTY_BYTE_ARRAY;
            }
            final HgContentRevision server = HgContentRevision.create(myProject, hgFile, serverRevisionNumber);
            mergeData.LAST = server.getContentAsBytes();
            file.refresh(false, false);
        }
    };
    VcsUtil.runVcsProcessWithProgress(runnable, VcsBundle.message("multiple.file.merge.loading.progress.title"), false, myProject);
    return mergeData;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) VcsRunnable(com.intellij.vcsUtil.VcsRunnable) HgContentRevision(org.zmlx.hg4idea.HgContentRevision) HgPromptCommandExecutor(org.zmlx.hg4idea.execution.HgPromptCommandExecutor) MergeData(com.intellij.openapi.vcs.merge.MergeData) ArrayList(java.util.ArrayList) HgCommandResultNotifier(org.zmlx.hg4idea.action.HgCommandResultNotifier) HgWorkingCopyRevisionsCommand(org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand) HgCommandResult(org.zmlx.hg4idea.execution.HgCommandResult) HgFile(org.zmlx.hg4idea.HgFile) HgRevisionNumber(org.zmlx.hg4idea.HgRevisionNumber) VirtualFile(com.intellij.openapi.vfs.VirtualFile) HgFile(org.zmlx.hg4idea.HgFile) File(java.io.File) NotNull(org.jetbrains.annotations.NotNull)

Example 12 with HgCommandResult

use of org.zmlx.hg4idea.execution.HgCommandResult in project intellij-community by JetBrains.

the class HgStatusCommand method executeInCurrentThread.

public Set<HgChange> executeInCurrentThread(VirtualFile repo, @Nullable Collection<FilePath> paths) {
    if (repo == null) {
        return Collections.emptySet();
    }
    HgCommandExecutor executor = new HgCommandExecutor(myProject);
    executor.setSilent(true);
    List<String> options = new LinkedList<>();
    if (myIncludeAdded) {
        options.add("--added");
    }
    if (myIncludeModified) {
        options.add("--modified");
    }
    if (myIncludeRemoved) {
        options.add("--removed");
    }
    if (myIncludeDeleted) {
        options.add("--deleted");
    }
    if (myIncludeUnknown) {
        options.add("--unknown");
    }
    if (myIncludeIgnored) {
        options.add("--ignored");
    }
    if (myIncludeCopySource) {
        options.add("--copies");
    }
    if (myCleanStatus) {
        options.add("--clean");
    }
    executor.setOutputAlwaysSuppressed(myCleanStatus || myIncludeUnknown || myIncludeIgnored);
    if (myBaseRevision != null && (!myBaseRevision.getRevision().isEmpty() || !myBaseRevision.getChangeset().isEmpty())) {
        options.add("--rev");
        options.add(StringUtil.isEmptyOrSpaces(myBaseRevision.getChangeset()) ? myBaseRevision.getRevision() : myBaseRevision.getChangeset());
        if (myTargetRevision != null) {
            options.add("--rev");
            options.add(myTargetRevision.getChangeset());
        }
    }
    final Set<HgChange> changes = new HashSet<>();
    if (paths != null) {
        final List<List<String>> chunked = VcsFileUtil.chunkPaths(repo, paths);
        for (List<String> chunk : chunked) {
            List<String> args = new ArrayList<>();
            args.addAll(options);
            args.addAll(chunk);
            HgCommandResult result = executor.executeInCurrentThread(repo, "status", args);
            changes.addAll(parseChangesFromResult(repo, result, args));
        }
    } else {
        HgCommandResult result = executor.executeInCurrentThread(repo, "status", options);
        changes.addAll(parseChangesFromResult(repo, result, options));
    }
    return changes;
}
Also used : HgCommandResult(org.zmlx.hg4idea.execution.HgCommandResult) HgCommandExecutor(org.zmlx.hg4idea.execution.HgCommandExecutor) HgChange(org.zmlx.hg4idea.HgChange)

Example 13 with HgCommandResult

use of org.zmlx.hg4idea.execution.HgCommandResult in project intellij-community by JetBrains.

the class HgUpdateCommand method updateRepoToInCurrentThread.

public static boolean updateRepoToInCurrentThread(@NotNull final Project project, @NotNull final VirtualFile repository, @NotNull final String targetRevision, final boolean clean) {
    final HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(project, repository);
    hgUpdateCommand.setRevision(targetRevision);
    hgUpdateCommand.setClean(clean);
    HgCommandResult result = hgUpdateCommand.execute();
    new HgConflictResolver(project).resolve(repository);
    boolean success = !HgErrorUtil.isCommandExecutionFailed(result);
    boolean hasUnresolvedConflicts = HgConflictResolver.hasConflicts(project, repository);
    if (!success) {
        new HgCommandResultNotifier(project).notifyError(result, "", "Update failed");
    } else if (hasUnresolvedConflicts) {
        new VcsNotifier(project).notifyImportantWarning("Unresolved conflicts.", HgVcsMessages.message("hg4idea.update.warning.merge.conflicts", repository.getPath()));
    }
    getRepositoryManager(project).updateRepository(repository);
    HgErrorUtil.markDirtyAndHandleErrors(project, repository);
    return success;
}
Also used : HgCommandResult(org.zmlx.hg4idea.execution.HgCommandResult) HgCommandResultNotifier(org.zmlx.hg4idea.action.HgCommandResultNotifier) HgConflictResolver(org.zmlx.hg4idea.provider.update.HgConflictResolver) VcsNotifier(com.intellij.openapi.vcs.VcsNotifier)

Example 14 with HgCommandResult

use of org.zmlx.hg4idea.execution.HgCommandResult in project intellij-community by JetBrains.

the class HgWorkingCopyRevisionsCommand method identify.

/**
   * Returns the result of 'hg id' execution, i.e. current state of the repository.
   * @return one or two revision numbers. Two revisions is the case of unresolved merge. In other cases there are only one revision.
   */
@NotNull
public Couple<HgRevisionNumber> identify(@NotNull VirtualFile repo) {
    HgCommandExecutor commandExecutor = new HgCommandExecutor(myProject);
    commandExecutor.setSilent(true);
    HgCommandResult result = commandExecutor.executeInCurrentThread(repo, "identify", Arrays.asList("--num", "--id"));
    if (result == null) {
        return Couple.of(HgRevisionNumber.NULL_REVISION_NUMBER, null);
    }
    final List<String> lines = result.getOutputLines();
    if (lines != null && !lines.isEmpty()) {
        List<String> parts = StringUtil.split(lines.get(0), " ");
        String changesets = parts.get(0);
        String revisions = parts.get(1);
        if (parts.size() >= 2) {
            if (changesets.indexOf('+') != changesets.lastIndexOf('+')) {
                // in the case of unresolved merge we have 2 revisions at once, both current, so with "+"
                // 9f2e6c02913c+b311eb4eb004+ 186+183+
                List<String> chsets = StringUtil.split(changesets, "+");
                List<String> revs = StringUtil.split(revisions, "+");
                return Couple.of(HgRevisionNumber.getInstance(revs.get(0) + "+", chsets.get(0) + "+"), HgRevisionNumber.getInstance(revs.get(1) + "+", chsets.get(1) + "+"));
            } else {
                return Couple.of(HgRevisionNumber.getInstance(revisions, changesets), null);
            }
        }
    }
    return Couple.of(HgRevisionNumber.NULL_REVISION_NUMBER, null);
}
Also used : HgCommandResult(org.zmlx.hg4idea.execution.HgCommandResult) HgCommandExecutor(org.zmlx.hg4idea.execution.HgCommandExecutor) NotNull(org.jetbrains.annotations.NotNull)

Example 15 with HgCommandResult

use of org.zmlx.hg4idea.execution.HgCommandResult in project intellij-community by JetBrains.

the class HgWorkingCopyRevisionsCommand method getRevisions.

/**
   * Returns the list of revisions returned by one mercurial commands (parents, identify, tip).
   * Executed a command on the whole repository or on the given file.
   * During a merge, the returned list contains 2 revision numbers. The order of these numbers is
   * important: the first parent was the parent of the working directory from <em>before</em>
   * the merge, the second parent is the changeset that was merged in.
   * @param repo     repository to execute on.
   * @param command  command to execute.
   * @param file     file which revisions are wanted. If <code><b>null</b></code> then repository revisions are considered.
   * @param revision revision to execute on. If <code><b>null</b></code> then executed without the '-r' parameter, i.e. on the latest revision.
   * @param silent   pass true if this command shouldn't be mentioned in the VCS console.
   * @return List of revisions.
   */
@NotNull
public List<HgRevisionNumber> getRevisions(@NotNull VirtualFile repo, @NotNull String command, @Nullable FilePath file, @Nullable HgRevisionNumber revision, boolean silent) {
    final List<String> args = new LinkedList<>();
    args.add("--template");
    args.add(HgChangesetUtil.makeTemplate("{rev}", "{node}"));
    if (revision != null) {
        args.add("-r");
        args.add(revision.getChangeset());
    }
    if (file != null) {
        // NB: this must be the last argument
        args.add(HgUtil.getOriginalFileName(file, ChangeListManager.getInstance(myProject)).getPath());
    }
    final HgCommandExecutor executor = new HgCommandExecutor(myProject);
    executor.setSilent(silent);
    final HgCommandResult result = executor.executeInCurrentThread(repo, command, args);
    if (result == null) {
        return new ArrayList<>(0);
    }
    final List<String> lines = new ArrayList<>();
    for (String line : result.getRawOutput().split(HgChangesetUtil.CHANGESET_SEPARATOR)) {
        if (!line.trim().isEmpty()) {
            // filter out empty lines
            lines.add(line);
        }
    }
    if (lines.isEmpty()) {
        return new ArrayList<>();
    }
    final List<HgRevisionNumber> revisions = new ArrayList<>(lines.size());
    for (String line : lines) {
        final List<String> parts = StringUtil.split(line, HgChangesetUtil.ITEM_SEPARATOR);
        if (parts.size() < 2) {
            LOG.error("getRevisions output parse error in line [" + line + "]\n All lines: \n" + lines);
            continue;
        }
        revisions.add(HgRevisionNumber.getInstance(parts.get(0), parts.get(1)));
    }
    return revisions;
}
Also used : HgCommandResult(org.zmlx.hg4idea.execution.HgCommandResult) HgCommandExecutor(org.zmlx.hg4idea.execution.HgCommandExecutor) HgRevisionNumber(org.zmlx.hg4idea.HgRevisionNumber) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

HgCommandResult (org.zmlx.hg4idea.execution.HgCommandResult)54 HgCommandExecutor (org.zmlx.hg4idea.execution.HgCommandExecutor)21 HgCommandResultNotifier (org.zmlx.hg4idea.action.HgCommandResultNotifier)19 Project (com.intellij.openapi.project.Project)12 NotNull (org.jetbrains.annotations.NotNull)11 ArrayList (java.util.ArrayList)7 HgVersion (org.zmlx.hg4idea.util.HgVersion)7 VcsException (com.intellij.openapi.vcs.VcsException)6 VirtualFile (com.intellij.openapi.vfs.VirtualFile)6 File (java.io.File)5 LinkedList (java.util.LinkedList)5 HgCommandResultHandler (org.zmlx.hg4idea.execution.HgCommandResultHandler)5 AccessToken (com.intellij.openapi.application.AccessToken)4 Nullable (org.jetbrains.annotations.Nullable)4 HgRevisionNumber (org.zmlx.hg4idea.HgRevisionNumber)4 HgVcs (org.zmlx.hg4idea.HgVcs)4 HgRevertCommand (org.zmlx.hg4idea.command.HgRevertCommand)4 SmartList (com.intellij.util.SmartList)3 HgFile (org.zmlx.hg4idea.HgFile)3 HgRemoteCommandExecutor (org.zmlx.hg4idea.execution.HgRemoteCommandExecutor)3