/*******************************************************************************
* Copyright (C) 2007, Robin Rosenberg <me@lathund.dewire.com>
* Copyright (C) 2006, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
* Copyright (C) 2013, Robin Stocker <robin@nibor.org>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.egit.core.internal.storage;
import java.io.IOException;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.history.IFileRevision;
/** An {@link IFileRevision} for the version in the Git index. */
public class IndexFileRevision extends GitFileRevision implements
OpenWorkspaceVersionEnabled {
// This is to maintain compatibility with the old behavior
private static final int FIRST_AVAILABLE = -1;
private final Repository db;
private final String path;
private final int stage;
private ObjectId blobId;
IndexFileRevision(final Repository repo, final String path) {
this(repo, path, FIRST_AVAILABLE);
}
IndexFileRevision(final Repository repo, final String path, int stage) {
super(path);
this.db = repo;
this.path = path;
this.stage = stage;
}
@Override
public IStorage getStorage(IProgressMonitor monitor) throws CoreException {
if (blobId == null)
blobId = locateBlobObjectId();
return new IndexBlobStorage(db, path, blobId);
}
@Override
public boolean isPropertyMissing() {
return false;
}
@Override
public String getAuthor() {
return ""; //$NON-NLS-1$
}
@Override
public long getTimestamp() {
return -1;
}
@Override
public String getComment() {
return null;
}
@Override
public String getContentIdentifier() {
return INDEX;
}
private ObjectId locateBlobObjectId() throws CoreException {
try {
DirCache dc = db.readDirCache();
int firstIndex = dc.findEntry(path);
if (firstIndex < 0)
return null;
// Try to avoid call to nextEntry if first entry already matches
DirCacheEntry firstEntry = dc.getEntry(firstIndex);
if (stage == FIRST_AVAILABLE || firstEntry.getStage() == stage)
return firstEntry.getObjectId();
// Ok, we have to search
int nextIndex = dc.nextEntry(firstIndex);
for (int i = firstIndex; i < nextIndex; i++) {
DirCacheEntry entry = dc.getEntry(i);
if (entry.getStage() == stage)
return entry.getObjectId();
}
return null;
} catch (IOException e) {
throw new CoreException(Activator.error(NLS.bind(
CoreText.IndexFileRevision_errorLookingUpPath, path), e));
}
}
@Override
public Repository getRepository() {
return db;
}
@Override
public String getGitPath() {
return path;
}
}