@Override @NotNull public LogData readAllHashes( @NotNull VirtualFile root, @NotNull final Consumer<TimedVcsCommit> commitConsumer) throws VcsException { if (!isRepositoryReady(root)) { return LogDataImpl.empty(); } List<String> parameters = new ArrayList<String>(GitHistoryUtils.LOG_ALL); parameters.add("--date-order"); final GitBekParentFixer parentFixer = GitBekParentFixer.prepare(root, this); Set<VcsUser> userRegistry = newHashSet(); Set<VcsRef> refs = newHashSet(); GitHistoryUtils.readCommits( myProject, root, parameters, new CollectConsumer<VcsUser>(userRegistry), new CollectConsumer<VcsRef>(refs), new Consumer<TimedVcsCommit>() { @Override public void consume(TimedVcsCommit commit) { commitConsumer.consume(parentFixer.fixCommit(commit)); } }); return new LogDataImpl(refs, userRegistry); }
@NotNull private DetailedLogData loadSomeCommitsOnTaggedBranches( @NotNull VirtualFile root, int commitCount, @NotNull Collection<String> unmatchedTags) throws VcsException { List<String> params = new ArrayList<String>(); params.add("--max-count=" + commitCount); params.addAll(unmatchedTags); return GitHistoryUtils.loadMetadata(myProject, root, true, ArrayUtil.toStringArray(params)); }
@NotNull public static List<String> prepareHashes(@NotNull List<String> hashes) { List<String> hashArgs = new ArrayList<String>(); for (String hash : hashes) { hashArgs.add("-r"); hashArgs.add(hash); } return hashArgs; }
@NotNull public static List<VcsCommitMetadata> loadMetadata( @NotNull final Project project, @NotNull final VirtualFile root, int limit, @NotNull List<String> parameters) throws VcsException { final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project); if (factory == null) { return Collections.emptyList(); } HgVcs hgvcs = HgVcs.getInstance(project); assert hgvcs != null; HgVersion version = hgvcs.getVersion(); List<String> templateList = HgBaseLogParser.constructDefaultTemplate(version); templateList.add("{desc}"); String[] templates = ArrayUtil.toStringArray(templateList); HgCommandResult result = getLogResult( project, root, version, limit, parameters, HgChangesetUtil.makeTemplate(templates)); HgBaseLogParser<VcsCommitMetadata> baseParser = new HgBaseLogParser<VcsCommitMetadata>() { @Override protected VcsCommitMetadata convertDetails( @NotNull String rev, @NotNull String changeset, @NotNull SmartList<HgRevisionNumber> parents, @NotNull Date revisionDate, @NotNull String author, @NotNull String email, @NotNull List<String> attributes) { String message = parseAdditionalStringAttribute(attributes, MESSAGE_INDEX); int subjectIndex = message.indexOf('\n'); String subject = subjectIndex == -1 ? message : message.substring(0, subjectIndex); List<Hash> parentsHash = new SmartList<Hash>(); for (HgRevisionNumber parent : parents) { parentsHash.add(factory.createHash(parent.getChangeset())); } return factory.createCommitMetadata( factory.createHash(changeset), parentsHash, revisionDate.getTime(), root, subject, author, email, message, author, email, revisionDate.getTime()); } }; return getCommitRecords(project, result, baseParser); }
@NotNull private DetailedLogData loadSomeCommitsOnTaggedBranches( @NotNull VirtualFile root, int commitCount, @NotNull Collection<String> unmatchedTags) throws VcsException { StopWatch sw = StopWatch.start("loading commits on tagged branch in " + root.getName()); List<String> params = new ArrayList<String>(); params.add("--max-count=" + commitCount); params.addAll(unmatchedTags); sw.report(); return GitHistoryUtils.loadMetadata(myProject, root, true, ArrayUtil.toStringArray(params)); }
@NotNull @Override public List<TimedVcsCommit> readAllHashes( @NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException { if (!isRepositoryReady(root)) { return Collections.emptyList(); } List<String> parameters = new ArrayList<String>(GitHistoryUtils.LOG_ALL); parameters.add("--sparse"); return GitHistoryUtils.readCommits(myProject, root, userRegistry, parameters); }
@NotNull @Override public List<? extends VcsFullCommitDetails> readFullDetails( @NotNull VirtualFile root, @NotNull List<String> hashes) throws VcsException { String noWalk = GitVersionSpecialty.NO_WALK_UNSORTED.existsIn(myVcs.getVersion()) ? "--no-walk=unsorted" : "--no-walk"; List<String> params = new ArrayList<String>(); params.add(noWalk); params.addAll(hashes); return GitHistoryUtils.history(myProject, root, ArrayUtil.toStringArray(params)); }
@NotNull public static Collection<String> getDescendingHeadsOfBranches( @NotNull Project project, @NotNull VirtualFile root, @NotNull Hash hash) throws VcsException { // hg log -r "descendants(659db54c1b6865c97c4497fa867194bcd759ca76) and head()" --template // "{branch}{bookmarks}" Set<String> branchHeads = new HashSet<String>(); List<String> params = new ArrayList<String>(); params.add("-r"); params.add("descendants(" + hash.asString() + ") and head()"); HgLogCommand hgLogCommand = new HgLogCommand(project); hgLogCommand.setLogFile(false); String template = HgChangesetUtil.makeTemplate("{branch}", "{bookmarks}"); HgCommandResult logResult = hgLogCommand.execute(root, template, -1, null, params); if (logResult == null || logResult.getExitValue() != 0) { throw new VcsException("Couldn't get commit details: log command execution error."); } String output = logResult.getRawOutput(); List<String> changeSets = StringUtil.split(output, HgChangesetUtil.CHANGESET_SEPARATOR); for (String line : changeSets) { List<String> attributes = StringUtil.split(line, HgChangesetUtil.ITEM_SEPARATOR); branchHeads.addAll(attributes); } return branchHeads; }
@NotNull private List<VcsCommitMetadata> loadSomeCommitsOnTaggedBranches( @NotNull VirtualFile root, int commitCount, @NotNull List<VcsRef> unmatchedHeads) throws VcsException { List<String> params = new ArrayList<String>( ContainerUtil.map( unmatchedHeads, new Function<VcsRef, String>() { @Override public String fun(VcsRef ref) { return ref.getCommitHash().asString(); } })); params.add("--max-count=" + commitCount); return GitHistoryUtils.loadMetadata(myProject, root, ArrayUtil.toStringArray(params)); }
@Nullable private static HgCommandResult getLogResult( @NotNull final Project project, @NotNull final VirtualFile root, @NotNull HgVersion version, int limit, @NotNull List<String> parameters, @NotNull String template) { HgFile originalHgFile = getOriginalHgFile(project, root); HgLogCommand hgLogCommand = new HgLogCommand(project); List<String> args = new ArrayList<String>(parameters); hgLogCommand.setLogFile(false); if (!version.isParentRevisionTemplateSupported()) { args.add("--debug"); } return hgLogCommand.execute(root, template, limit, originalHgFile, args); }
@NotNull @Override public List<TimedVcsCommit> getCommitsMatchingFilter( @NotNull final VirtualFile root, @NotNull VcsLogFilterCollection filterCollection, int maxCount) throws VcsException { if (!isRepositoryReady(root)) { return Collections.emptyList(); } List<String> filterParameters = ContainerUtil.newArrayList(); if (filterCollection.getBranchFilter() != null && !filterCollection.getBranchFilter().getBranchNames().isEmpty()) { GitRepository repository = getRepository(root); assert repository != null : "repository is null for root " + root + " but was previously reported as 'ready'"; boolean atLeastOneBranchExists = false; for (String branchName : filterCollection.getBranchFilter().getBranchNames()) { if (branchName.equals("HEAD") || repository.getBranches().findBranchByName(branchName) != null) { filterParameters.add(branchName); atLeastOneBranchExists = true; } } if (!atLeastOneBranchExists) { // no such branches in this repository => filter matches // nothing return Collections.emptyList(); } } else { filterParameters.addAll(GitHistoryUtils.LOG_ALL); } if (filterCollection.getUserFilter() != null) { String authorFilter = StringUtil.join( ContainerUtil.map( filterCollection.getUserFilter().getUserNames(root), UserNameRegex.INSTANCE), "|"); filterParameters.add(prepareParameter("author", StringUtil.escapeBackSlashes(authorFilter))); filterParameters.add( "--extended-regexp"); // extended regexp required for correctly filtering user names } if (filterCollection.getDateFilter() != null) { // assuming there is only one date filter, until filter expressions are defined VcsLogDateFilter filter = filterCollection.getDateFilter(); if (filter.getAfter() != null) { filterParameters.add(prepareParameter("after", filter.getAfter().toString())); } if (filter.getBefore() != null) { filterParameters.add(prepareParameter("before", filter.getBefore().toString())); } } if (filterCollection.getTextFilter() != null) { String textFilter = filterCollection.getTextFilter().getText(); filterParameters.add(prepareParameter("grep", StringUtil.escapeChars(textFilter, '[', ']'))); } filterParameters.add( "--regexp-ignore-case"); // affects case sensitivity of any filter (except file filter) if (maxCount > 0) { filterParameters.add(prepareParameter("max-count", String.valueOf(maxCount))); } // note: structure filter must be the last parameter, because it uses "--" which separates // parameters from paths if (filterCollection.getStructureFilter() != null) { Collection<VirtualFile> files = filterCollection.getStructureFilter().getFiles(); if (!files.isEmpty()) { filterParameters.add("--full-history"); filterParameters.add("--simplify-merges"); filterParameters.add("--"); for (VirtualFile file : files) { filterParameters.add(file.getPath()); } } } List<TimedVcsCommit> commits = ContainerUtil.newArrayList(); GitHistoryUtils.readCommits( myProject, root, filterParameters, EmptyConsumer.<VcsUser>getInstance(), EmptyConsumer.<VcsRef>getInstance(), new CollectConsumer<TimedVcsCommit>(commits)); return commits; }
public static List<? extends VcsFullCommitDetails> createFullCommitsFromResult( @NotNull Project project, @NotNull VirtualFile root, @Nullable HgCommandResult result, @NotNull HgVersion version, boolean silent) { final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project); if (factory == null) { return Collections.emptyList(); } List<HgFileRevision> hgRevisions = getCommitRecords( project, result, new HgFileRevisionLogParser(project, getOriginalHgFile(project, root), version), silent); List<VcsFullCommitDetails> vcsFullCommitDetailsList = new ArrayList<VcsFullCommitDetails>(); for (HgFileRevision revision : hgRevisions) { HgRevisionNumber vcsRevisionNumber = revision.getRevisionNumber(); List<HgRevisionNumber> parents = vcsRevisionNumber.getParents(); HgRevisionNumber firstParent = parents.isEmpty() ? null : parents.get(0); // can have no parents if it is a root List<Hash> parentsHash = new SmartList<Hash>(); for (HgRevisionNumber parent : parents) { parentsHash.add(factory.createHash(parent.getChangeset())); } final Collection<Change> changes = new ArrayList<Change>(); for (String file : revision.getModifiedFiles()) { changes.add( createChange( project, root, file, firstParent, file, vcsRevisionNumber, FileStatus.MODIFIED)); } for (String file : revision.getAddedFiles()) { changes.add( createChange(project, root, null, null, file, vcsRevisionNumber, FileStatus.ADDED)); } for (String file : revision.getDeletedFiles()) { changes.add( createChange( project, root, file, firstParent, null, vcsRevisionNumber, FileStatus.DELETED)); } for (Map.Entry<String, String> copiedFile : revision.getCopiedFiles().entrySet()) { changes.add( createChange( project, root, copiedFile.getKey(), firstParent, copiedFile.getValue(), vcsRevisionNumber, FileStatus.ADDED)); } vcsFullCommitDetailsList.add( factory.createFullDetails( factory.createHash(vcsRevisionNumber.getChangeset()), parentsHash, revision.getRevisionDate().getTime(), root, vcsRevisionNumber.getSubject(), vcsRevisionNumber.getAuthor(), vcsRevisionNumber.getEmail(), vcsRevisionNumber.getCommitMessage(), vcsRevisionNumber.getAuthor(), vcsRevisionNumber.getEmail(), revision.getRevisionDate().getTime(), new ThrowableComputable<Collection<Change>, Exception>() { @Override public Collection<Change> compute() throws Exception { return changes; } })); } return vcsFullCommitDetailsList; }