/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* See LICENSE.txt included in this distribution for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at LICENSE.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/**
* Access to a Mercurial repository.
*/
/** The property name used to obtain the client command for thisrepository. */
/** The command to use to access the repository if none was given explicitly */
/** The boolean property and environment variable name to indicate
* whether forest-extension in Mercurial adds repositories inside the
* repositories. */
/** Template for formatting hg log output for files. */
"changeset: {rev}:{node|short}\\n"
+ "{branches}{tags}{parents}\\n"
+ "user: {author}\\ndate: {date|rfc3339date}\\n"
+ "description: {desc|strip|obfuscate}\\n",
"changeset: {rev}:{node|short}:{node}\\n"
+ "{branches}{tags}{parents}\\n"
+ "user: {author}\\ndate: {date|rfc3339date}\\n"
+ "description: {desc|strip|obfuscate}\\n"
};
/** Template for formatting hg log output for directories. */
};
// 0 .. normal repo, 1 .. bridged repo, i.e "cloned" from a different type
private int style;
private long lastModOldRev;
/**
* Create a new instance of type {@code Mercurial}.
*/
public MercurialRepository() {
type = "Mercurial";
if (DATE_PATTERN == null) {
if (RuntimeEnvironment.isOldJVM()) {
DATE_PATTERN = "yyyy-MM-dd hh:mm ZZZZ";
} else {
DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ssXXX";
}
}
}
try {
f.deleteOnExit();
out = new FileWriter(f, false);
// actually mercurial needs to provide a way to escape certain
// chars in filenames, to get this 100% correct
} finally {
}
}
}
// package scope: MercurialHistoryParser.java is the only consumer
/**
* Get the mapping of this repository based revisions to the revisions of
* the non-hybrid repository. Key is the full hg revision aka
* 'node', the corresponding value is the revision string in the non-hybrid
* repository.
* @return an empty map, if this is a native mercurial repository or is not
* a hybrid (like hgsubversion), the fully populated map otherwise.
*/
return oldRevMap;
}
if (! f.exists()) {
return oldRevMap;
}
long t = f.lastModified();
if (t <= lastModOldRev) {
return oldRevMap;
}
lastModOldRev = t;
}
if (idx > 0) {
}
}
} catch (IOException e) {
}
}
oldRevMap = m;
return oldRevMap;
}
/**
* Get the UUID assigned by hgsubversion to the repository.
* @return {@code null} if this is not a subversion hybrid repository,
* the hgsubversion UUID otherwise.
*/
if (f.exists()) {
} catch (IOException e) {
}
}
}
svnUUID = "";
style = 0;
} else {
style = 1;
}
}
}
/**
* {@inheritDoc}
*/
if (this.directoryName != null
{
throw new IllegalArgumentException("Software bug: directory is "
+ directoryName + ")");
}
super.setDirectoryName(directoryName);
getSvnUUID(); // trigger style adjustments
}
/**
* Get an executor to be used for retrieving the history log for the
* named file. When indexing it gets usually called twice: 1st without any
* -r option, 2nd with -r $currentRev:tip.
*
* @param file The file to retrieve history for (canonical path incl. source
* root).
* @param changeset the oldest changeset to return from the executor,
* or {@code null} if all changesets should be returned
* @return An Executor ready to be started
*/
throws HistoryException, IOException
{
}
}
} else {
throw new HistoryException("Don't know how to parse changeset "
}
}
if (file.isDirectory()) {
} else {
}
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("resource")
{
}
try {
return null;
}
int len;
if (len > 0) {
}
}
} finally {
// Clean up zombie-processes...
try {
} catch (IllegalThreadStateException exp) {
// the process is still running??? just kill it..
}
}
}
return ret;
}
/**
* {@inheritDoc}
*/
} else {
}
}
// Construct hash map for history entries from history cache. This is
// needed later to get user string for particular revision.
try {
// Chop out the colon and all hexadecimal what follows.
// This is because the whole changeset identification is
// stored in history index while annotate only needs the
// revision identifier.
}
} catch (HistoryException he) {
return null;
}
try {
int lineno = 0;
}
++lineno;
// Use the history index hash map to get the author.
// no different strings for the same author
// hgsubversioned entries have no e-mail
? author
}
}
}
} else {
}
}
} finally {
try {
} catch (IllegalThreadStateException e) {
// the process is still running??? just kill it..
}
}
}
return ret;
}
/**
* {@inheritDoc}
*/
return true;
}
/**
* {@inheritDoc}
*/
}
}
}
}
/**
* {@inheritDoc}
*/
// Todo: is there a cheap test for whether mercurial has history
// available for a file?
// Otherwise, this is harmless, since mercurial's commands will just
// print nothing if there is no history.
return true;
}
/**
* {@inheritDoc}
*/
if (file.isDirectory()) {
return f.exists() && f.isDirectory();
}
return false;
}
/**
* {@inheritDoc}
*/
public boolean supportsSubRepositories() {
}
/**
* {@inheritDoc}
*/
public boolean isWorking() {
}
return working.booleanValue();
}
/**
* {@inheritDoc}
*/
public boolean hasHistoryForDirectories() {
return true;
}
/**
* {@inheritDoc}
*/
}
/**
* {@inheritDoc}
*/
throws HistoryException
{
try {
{
return new History();
}
} catch (IOException e) {
return new History();
}
}
}