Collection<Change> startProcessingChanges(final Project project, @Nullable final VcsDirtyScope scope) { createReadChangesCache(); final Collection<Change> result = new ArrayList<Change>(); myChangesBeforeUpdate = new OpenTHashSet<Change>(myChanges); for (Change oldBoy : myChangesBeforeUpdate) { final ContentRevision before = oldBoy.getBeforeRevision(); final ContentRevision after = oldBoy.getAfterRevision(); if (scope == null || before != null && scope.belongsTo(before.getFile()) || after != null && scope.belongsTo(after.getFile()) || isIgnoredChange(oldBoy, project)) { result.add(oldBoy); myChanges.remove(oldBoy); myReadChangesCache = null; } } return result; }
Collection<Change> startProcessingChanges(final Project project, @Nullable final VcsDirtyScope scope) { createReadChangesCache(); final Collection<Change> result = new ArrayList<Change>(); myChangesBeforeUpdate = new OpenTHashSet<Change>(myChanges); final FileIndexFacade fileIndex = PeriodicalTasksCloser.getInstance().safeGetService(project, FileIndexFacade.class); for (Change oldBoy : myChangesBeforeUpdate) { final ContentRevision before = oldBoy.getBeforeRevision(); final ContentRevision after = oldBoy.getAfterRevision(); if (scope == null || before != null && scope.belongsTo(before.getFile()) || after != null && scope.belongsTo(after.getFile()) || isIgnoredChange(oldBoy, fileIndex)) { result.add(oldBoy); myChanges.remove(oldBoy); myReadChangesCache = null; } } return result; }
private void checkAndScheduleFileNameChange(@Nullable OpenTHashSet<String> actualNames, VirtualFile child) { if (actualNames != null) { String currentName = child.getName(); String actualName = actualNames.get(currentName); if (actualName != null && !currentName.equals(actualName)) { scheduleAttributeChange(child, VirtualFile.PROP_NAME, currentName, actualName); } } }
@NotNull public static VcsLogProvider.DetailedLogData loadMetadata(@NotNull final Project project, @NotNull final VirtualFile root, final boolean withRefs, String... params) throws VcsException { final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project); if (factory == null) { return LogDataImpl.empty(); } final Set<VcsRef> refs = new OpenTHashSet<VcsRef>(GitLogProvider.DONT_CONSIDER_SHA); final List<VcsCommitMetadata> commits = loadDetails(project, root, withRefs, false, new NullableFunction<GitLogRecord, VcsCommitMetadata>() { @Nullable @Override public VcsCommitMetadata fun(GitLogRecord record) { GitCommit commit = createCommit(project, root, record, factory); if (withRefs) { Collection<VcsRef> refsInRecord = parseRefs(record.getRefs(), commit.getId(), factory, root); for (VcsRef ref : refsInRecord) { if (!refs.add(ref)) { LOG.error("Adding duplicate element to the set"); } } } return commit; } }, params); return new LogDataImpl(refs, commits); }
@NotNull @Override public DetailedLogData readFirstBlock(@NotNull VirtualFile root, @NotNull Requirements requirements) throws VcsException { if (!isRepositoryReady(root)) { return LogDataImpl.empty(); } GitRepository repository = ObjectUtils.assertNotNull(myRepositoryManager.getRepositoryForRoot(root)); // need to query more to sort them manually; this doesn't affect performance: it is equal for -1000 and -2000 int commitCount = requirements.getCommitCount() * 2; String[] params = new String[]{"HEAD", "--branches", "--remotes", "--max-count=" + commitCount}; // NB: not specifying --tags, because it introduces great slowdown if there are many tags, // but makes sense only if there are heads without branch or HEAD labels (rare case). Such cases are partially handled below. boolean refresh = requirements instanceof VcsLogProviderRequirementsEx && ((VcsLogProviderRequirementsEx)requirements).isRefresh(); DetailedLogData data = GitHistoryUtils.loadMetadata(myProject, root, true, params); Set<VcsRef> safeRefs = data.getRefs(); Set<VcsRef> allRefs = new OpenTHashSet<VcsRef>(safeRefs, DONT_CONSIDER_SHA); Set<VcsRef> branches = readBranches(repository); addNewElements(allRefs, branches); Collection<VcsCommitMetadata> allDetails; Set<String> currentTagNames = null; DetailedLogData commitsFromTags = null; if (!refresh) { allDetails = data.getCommits(); } else { // on refresh: get new tags, which point to commits not from the first block; then get history, walking down just from these tags // on init: just ignore such tagged-only branches. The price for speed-up. VcsLogProviderRequirementsEx rex = (VcsLogProviderRequirementsEx)requirements; currentTagNames = readCurrentTagNames(root); addOldStillExistingTags(allRefs, currentTagNames, rex.getPreviousRefs()); allDetails = newHashSet(data.getCommits()); Set<String> previousTags = newHashSet(ContainerUtil.mapNotNull(rex.getPreviousRefs(), GET_TAG_NAME)); Set<String> safeTags = newHashSet(ContainerUtil.mapNotNull(safeRefs, GET_TAG_NAME)); Set<String> newUnmatchedTags = remove(currentTagNames, previousTags, safeTags); if (!newUnmatchedTags.isEmpty()) { commitsFromTags = loadSomeCommitsOnTaggedBranches(root, commitCount, newUnmatchedTags); addNewElements(allDetails, commitsFromTags.getCommits()); addNewElements(allRefs, commitsFromTags.getRefs()); } } StopWatch sw = StopWatch.start("sorting commits in " + root.getName()); List<VcsCommitMetadata> sortedCommits = VcsLogSorter.sortByDateTopoOrder(allDetails); sortedCommits = sortedCommits.subList(0, Math.min(sortedCommits.size(), requirements.getCommitCount())); sw.report(); if (LOG.isDebugEnabled()) { validateDataAndReportError(root, allRefs, sortedCommits, data, branches, currentTagNames, commitsFromTags); } return new LogDataImpl(allRefs, sortedCommits); }