/** * Given the list of paths converts them to the list of {@link Change Changes} found in the {@link * ChangeListManager}, i.e. this works only for local changes. </br> Paths can be absolute or * relative to the repository. If a path is not found in the local changes, it is ignored, but the * fact is logged. */ @NotNull public static List<Change> findLocalChangesForPaths( @NotNull Project project, @NotNull VirtualFile root, @NotNull Collection<String> affectedPaths, boolean relativePaths) { ChangeListManagerEx changeListManager = (ChangeListManagerEx) ChangeListManager.getInstance(project); List<Change> affectedChanges = new ArrayList<Change>(); for (String path : affectedPaths) { String absolutePath = relativePaths ? toAbsolute(root, path) : path; VirtualFile file = findRefreshFileOrLog(absolutePath); if (file != null) { Change change = changeListManager.getChange(file); if (change != null) { affectedChanges.add(change); } else { String message = "Change is not found for " + file.getPath(); if (changeListManager.isInUpdate()) { message += " because ChangeListManager is being updated."; } LOG.warn(message); } } } return affectedChanges; }
private static String parseRefs( SymbolicRefsI refs, Collection<String> currentRefs, List<String> locals, List<String> remotes, List<String> tags) { if (refs == null) return null; for (String ref : currentRefs) { final SymbolicRefs.Kind kind = refs.getKind(ref); if (SymbolicRefs.Kind.LOCAL.equals(kind)) { locals.add(ref); } else if (SymbolicRefs.Kind.REMOTE.equals(kind)) { remotes.add(ref); } else { tags.add(ref); } } if (refs.getCurrent() != null && currentRefs.contains(refs.getCurrent().getName())) return refs.getCurrent().getName(); return null; }
public static List<GitCommit> commitsDetails( Project project, FilePath path, SymbolicRefsI refs, final Collection<String> commitsIds) throws VcsException { // adjust path using change manager path = getLastCommitName(project, path); final VirtualFile root = GitUtil.getGitRoot(path); GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.SHOW); GitLogParser parser = new GitLogParser( project, GitLogParser.NameStatus.STATUS, SHORT_HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, COMMITTER_EMAIL, SHORT_PARENTS, REF_NAMES, SUBJECT, BODY, RAW_BODY); h.setNoSSH(true); h.setStdoutSuppressed(true); h.addParameters("--name-status", parser.getPretty(), "--encoding=UTF-8"); h.addParameters(new ArrayList<String>(commitsIds)); // h.endOptions(); // h.addRelativePaths(path); String output; try { output = h.run(); final List<GitCommit> rc = new ArrayList<GitCommit>(); for (GitLogRecord record : parser.parse(output)) { final GitCommit gitCommit = createCommit(project, refs, root, record); rc.add(gitCommit); } return rc; } catch (VcsException e) { throw e; } }
/** * Sort files by vcs root * * @param files files to sort. * @param ignoreNonGit if true, non-git files are ignored * @return the map from root to the files under the root * @throws VcsException if non git files are passed when {@code ignoreNonGit} is false */ @NotNull public static Map<VirtualFile, List<FilePath>> sortFilePathsByGitRoot( @NotNull Collection<FilePath> files, boolean ignoreNonGit) throws VcsException { Map<VirtualFile, List<FilePath>> rc = new HashMap<VirtualFile, List<FilePath>>(); for (FilePath p : files) { VirtualFile root = getGitRootOrNull(p); if (root == null) { if (ignoreNonGit) { continue; } else { throw new VcsException("The file " + p.getPath() + " is not under Git"); } } List<FilePath> l = rc.get(root); if (l == null) { l = new ArrayList<FilePath>(); rc.put(root, l); } l.add(p); } return rc; }
/** * Sort files by Git root * * @param virtualFiles files to sort * @param ignoreNonGit if true, non-git files are ignored * @return sorted files * @throws VcsException if non git files are passed when {@code ignoreNonGit} is false */ public static Map<VirtualFile, List<VirtualFile>> sortFilesByGitRoot( Collection<VirtualFile> virtualFiles, boolean ignoreNonGit) throws VcsException { Map<VirtualFile, List<VirtualFile>> result = new HashMap<VirtualFile, List<VirtualFile>>(); for (VirtualFile file : virtualFiles) { // directory is reported only when it is a submodule => it should be treated in the context of // super-root final VirtualFile vcsRoot = gitRootOrNull(file.isDirectory() ? file.getParent() : file); if (vcsRoot == null) { if (ignoreNonGit) { continue; } else { throw new VcsException("The file " + file.getPath() + " is not under Git"); } } List<VirtualFile> files = result.get(vcsRoot); if (files == null) { files = new ArrayList<VirtualFile>(); result.put(vcsRoot, files); } files.add(file); } return result; }
private RebaseInfo collectRebaseInfo() { final Set<VirtualFile> roots = new HashSet<VirtualFile>(); final Set<VirtualFile> rootsWithMerges = new HashSet<VirtualFile>(); final Map<VirtualFile, List<String>> reorderedCommits = new HashMap<VirtualFile, List<String>>(); final Map<VirtualFile, Set<String>> uncheckedCommits = new HashMap<VirtualFile, Set<String>>(); for (int i = 0; i < myTreeRoot.getChildCount(); i++) { CheckedTreeNode node = (CheckedTreeNode) myTreeRoot.getChildAt(i); Root r = (Root) node.getUserObject(); Set<String> unchecked = new HashSet<String>(); uncheckedCommits.put(r.root, unchecked); if (r.commits.size() == 0) { if (r.remoteCommits > 0) { roots.add(r.root); } continue; } boolean seenCheckedNode = false; boolean reorderNeeded = false; boolean seenMerges = false; for (int j = 0; j < node.getChildCount(); j++) { if (node.getChildAt(j) instanceof CheckedTreeNode) { CheckedTreeNode commitNode = (CheckedTreeNode) node.getChildAt(j); Commit commit = (Commit) commitNode.getUserObject(); seenMerges |= commit.isMerge; if (commitNode.isChecked()) { seenCheckedNode = true; } else { unchecked.add(commit.commitId()); if (seenCheckedNode) { reorderNeeded = true; } } } } if (seenMerges) { rootsWithMerges.add(r.root); } if (r.remoteCommits > 0 || reorderNeeded) { roots.add(r.root); } if (reorderNeeded) { List<String> reordered = new ArrayList<String>(); for (int j = 0; j < node.getChildCount(); j++) { if (node.getChildAt(j) instanceof CheckedTreeNode) { CheckedTreeNode commitNode = (CheckedTreeNode) node.getChildAt(j); if (!commitNode.isChecked()) { Commit commit = (Commit) commitNode.getUserObject(); reordered.add(commit.revision.asString()); } } } for (int j = 0; j < node.getChildCount(); j++) { if (node.getChildAt(j) instanceof CheckedTreeNode) { CheckedTreeNode commitNode = (CheckedTreeNode) node.getChildAt(j); if (commitNode.isChecked()) { Commit commit = (Commit) commitNode.getUserObject(); reordered.add(commit.revision.asString()); } } } Collections.reverse(reordered); reorderedCommits.put(r.root, reordered); } } final GitVcsSettings.UpdateChangesPolicy p = UpdatePolicyUtils.getUpdatePolicy(myStashRadioButton, myShelveRadioButton); assert p == GitVcsSettings.UpdateChangesPolicy.STASH || p == GitVcsSettings.UpdateChangesPolicy.SHELVE; return new RebaseInfo(reorderedCommits, rootsWithMerges, uncheckedCommits, roots, p); }