750N/A * The contents of this file are subject to the terms of the 750N/A * Common Development and Distribution License (the "License"). 750N/A * You may not use this file except in compliance with the License. 750N/A * language governing permissions and limitations under the License. 750N/A * When distributing Covered Code, include this CDDL HEADER in each 750N/A * If applicable, add the following below this CDDL HEADER, with the 750N/A * fields enclosed by brackets "[]" replaced with your own identifying 750N/A * information: Portions Copyright [yyyy] [name of copyright owner] 750N/A * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. 750N/A * Class representing file based storage of per source file history. 796N/A * Generate history for single file. 796N/A * @param map_entry entry mapping filename to list of history entries 796N/A * @param env runtime environment 796N/A * @param repository repository object in which the file belongs 796N/A * @param test file object 796N/A * @param root root of the source repository 796N/A * @param renamed true if the files was renamed in the past 796N/A * Certain files require special handling - this is mainly for 796N/A * files which have been renamed in Mercurial repository. 796N/A * This ensures that their complete history (follow) will be // File based history cache does not store files for individual // changesets so strip them. // add all history entries // Assign tags to changesets they represent. // all repositories are supported * Get a <code>File</code> object describing the cache file. * @param file the file to find the cache for * @return file that might contain cached history for <code>file</code> "source root for " +
file, e);
* Read history from a file. * Store history object (encoded as XML and compressed with gzip) in a file. * @param history history object to store * @param file file to store the history object into * @param repo repository for the file * @throws HistoryException "Unable to create cache directory '" +
dir +
"'.");
// Incremental update of the history for this file. // Merge old history with the new history. // Retag the last changesets in case there have been some new // tags added to the repository. Technically we should just // retag the last revision from the listOld however this // does not solve the problem when listNew contains new tags // retroactively tagging changesets from listOld so we resort // to this somewhat crude solution. // Ideally we would want to catch the case when incremental update // is done but the cached file is not there however we do not have // the data to do it here. // We have a problem that multiple threads may access the cache layer // at the same time. Since I would like to avoid read-locking, I just // serialize the write access to the cache file. The generation of the // cache file would most likely be executed during index generation, and // that happens sequencial anyway.... // Generate the file with a temporary name and move it into place when // I'm done so I don't have to protect the readers for partially updated "Failed to remove temporary history cache file");
"Cachefile exists, and I could not delete it.");
"Failed to remove temporary history cache file");
"Done storing history for repo {0}",
* Store history for the whole repository in directory hierarchy resembling * the original repository structure. History of individual files will be * stored under this hierarchy, each file containing history of * corresponding source file. * @param history history object to process into per-file histories * @param repository repository object * @throws HistoryException // Return immediately when there is nothing to do. "Storing history for repo {0}",
* Go through all history entries for this repository (acquired through * history/log command executed for top-level directory of the repo * and parsed into HistoryEntry structures) and create hash map which * maps file names into list of HistoryEntry structures corresponding * to changesets in which the file was modified. // The history entries are sorted from newest to oldest. * We do not want to generate history cache for files which * do not currently exist in the repository. * We need to do deep copy in order to have different tags * Now traverse the list of files from the hash map built above * and for each file store its history (saved in the value of the * hash map entry for the file) in a file. Skip renamed files * which will be handled separately below. "isRenamedFile() got exception " ,
ex);
* Now handle renamed files (in parallel). "isRenamedFile() got exception ",
ex);
// The directories for the renamed files have to be created before // the actual files otherwise storeFile() might be racing for // mkdirs() if there are multiple renamed files from single directory "Unable to create cache directory ' {0} '.",
dir);
// We want to catch any exception since we are in thread. "doFileHistory() got exception ",
ex);
// Wait for the executors to finish. // Wait for the executors to finish. "Error when reading cache file '" +
cache, e);
* Some mirrors of repositories which are capable of fetching history * for directories may contain lots of files untracked by given SCM. * For these it would be waste of time to get their history * since the history of all files in this repository should have been * fetched in the first phase of indexing. // In this case, we've found a file for which the SCM has no history // An example is a non-SCCS file somewhere in an SCCS-controlled // Don't cache history-information for directories, since the // history information on the directory may change if a file in // a sub-directory change. This will cause us to present a stale // history log until a the current directory is updated and // invalidates the cache entry. // retrieving the history takes too long, cache it! * Check if the cache is up to date for the specified file. * @param file the file to check * @param cachedFile the file which contains the cached history for * @return {@code true} if the cache is up to date, {@code false} otherwise * Check if the directory is in the cache. * @param directory the directory to check * @return {@code true} if the directory is in the cache * Store latest indexed revision for the repository under data directory. * @param repository repository * @param rev latest revision which has been just indexed // We don't have a good way to get this information from the file // cache, so leave it to the caller to find a reasonable time to // display (typically the last modified time on the file system). // remove the file cached last revision (done separately in case // it gets ever moved outside of the hierarchy) // Remove all files which constitute the history cache.