@ -43,31 +43,30 @@
package org.eclipse.jgit.internal.storage.dfs ;
import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX ;
import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK ;
import java.io.FileNotFoundException ;
import java.io.IOException ;
import java.util.List ;
import org.eclipse.jgit.errors.CorruptPackIndexException ;
import org.eclipse.jgit.errors.MissingObjectException ;
import org.eclipse.jgit.internal.JGitText ;
import org.eclipse.jgit.internal.fsck.FsckError ;
import org.eclipse.jgit.internal.fsck.FsckError.CorruptIndex ;
import org.eclipse.jgit.internal.fsck.FsckPackParser ;
import org.eclipse.jgit.internal.storage.pack.PackExt ;
import org.eclipse.jgit.lib.Constants ;
import org.eclipse.jgit.lib.NullProgressMonitor ;
import org.eclipse.jgit.lib.ObjectChecker ;
import org.eclipse.jgit.lib.ProgressMonitor ;
import org.eclipse.jgit.lib.Ref ;
import org.eclipse.jgit.revwalk.ObjectWalk ;
import org.eclipse.jgit.revwalk.RevObject ;
import org.eclipse.jgit.transport.PackedObjectInfo ;
/** Verify the validity and connectivity of a DFS repository. */
public class DfsFsck {
private final DfsRepository repo ;
private final DfsObjDatabase objdb ;
private final DfsReader ctx ;
private ObjectChecker objChecker = new ObjectChecker ( ) ;
/ * *
@ -79,10 +78,8 @@ public class DfsFsck {
public DfsFsck ( DfsRepository repository ) {
repo = repository ;
objdb = repo . getObjectDatabase ( ) ;
ctx = objdb . newReader ( ) ;
}
/ * *
* Verify the integrity and connectivity of all objects in the object
* database .
@ -94,55 +91,72 @@ public class DfsFsck {
* if encounters IO errors during the process .
* /
public FsckError check ( ProgressMonitor pm ) throws IOException {
if ( pm = = null ) {
pm = NullProgressMonitor . INSTANCE ;
}
FsckError errors = new FsckError ( ) ;
try {
checkPacks ( pm , errors ) ;
checkConnectivity ( pm , errors ) ;
return errors ;
}
private void checkPacks ( ProgressMonitor pm , FsckError errors )
throws IOException , FileNotFoundException {
try ( DfsReader ctx = objdb . newReader ( ) ) {
for ( DfsPackFile pack : objdb . getPacks ( ) ) {
DfsPackDescription packDesc = pack . getPackDescription ( ) ;
try ( ReadableChannel channel = repo . getObjectDatabase ( )
. openFile ( packDesc , PackExt . PACK ) ) {
List < PackedObjectInfo > objectsInPack ;
FsckPackParser parser = new FsckPackParser (
repo . getObjectDatabase ( ) , channel ) ;
parser . setObjectChecker ( objChecker ) ;
parser . overwriteObjectCount ( packDesc . getObjectCount ( ) ) ;
parser . parse ( pm ) ;
errors . getCorruptObjects ( )
. addAll ( parser . getCorruptObjects ( ) ) ;
objectsInPack = parser . getSortedObjectList ( null ) ;
parser . verifyIndex ( objectsInPack , pack . getPackIndex ( ctx ) ) ;
try ( ReadableChannel rc = objdb . openFile ( packDesc , PACK ) ) {
verifyPack ( pm , errors , ctx , pack , rc ) ;
} catch ( MissingObjectException e ) {
errors . getMissingObjects ( ) . add ( e . getObjectId ( ) ) ;
} catch ( CorruptPackIndexException e ) {
errors . getCorruptIndices ( ) . add ( new CorruptIndex (
pack . getPackDescription ( )
. getFileName ( PackExt . INDEX ) ,
pack . getPackDescription ( ) . getFileName ( INDEX ) ,
e . getErrorType ( ) ) ) ;
}
}
}
}
private void verifyPack ( ProgressMonitor pm , FsckError errors , DfsReader ctx ,
DfsPackFile pack , ReadableChannel ch )
throws IOException , CorruptPackIndexException {
FsckPackParser fpp = new FsckPackParser ( objdb , ch ) ;
fpp . setObjectChecker ( objChecker ) ;
fpp . overwriteObjectCount ( pack . getPackDescription ( ) . getObjectCount ( ) ) ;
fpp . parse ( pm ) ;
errors . getCorruptObjects ( ) . addAll ( fpp . getCorruptObjects ( ) ) ;
fpp . verifyIndex ( pack . getPackIndex ( ctx ) ) ;
}
try ( ObjectWalk ow = new ObjectWalk ( ctx ) ) {
for ( Ref r : repo . getAllRefs ( ) . values ( ) ) {
try {
RevObject tip = ow . parseAny ( r . getObjectId ( ) ) ;
if ( r . getLeaf ( ) . getName ( ) . startsWith ( Constants . R_HEADS ) ) {
// check if heads point to a commit object
if ( tip . getType ( ) ! = Constants . OBJ_COMMIT ) {
errors . getNonCommitHeads ( )
. add ( r . getLeaf ( ) . getName ( ) ) ;
}
}
ow . markStart ( tip ) ;
ow . checkConnectivity ( ) ;
ow . markUninteresting ( tip ) ;
} catch ( MissingObjectException e ) {
errors . getMissingObjects ( ) . add ( e . getObjectId ( ) ) ;
private void checkConnectivity ( ProgressMonitor pm , FsckError errors )
throws IOException {
pm . beginTask ( JGitText . get ( ) . countingObjects , ProgressMonitor . UNKNOWN ) ;
try ( ObjectWalk ow = new ObjectWalk ( repo ) ) {
for ( Ref r : repo . getAllRefs ( ) . values ( ) ) {
RevObject tip ;
try {
tip = ow . parseAny ( r . getObjectId ( ) ) ;
if ( r . getLeaf ( ) . getName ( ) . startsWith ( Constants . R_HEADS )
& & tip . getType ( ) ! = Constants . OBJ_COMMIT ) {
// heads should only point to a commit object
errors . getNonCommitHeads ( ) . add ( r . getLeaf ( ) . getName ( ) ) ;
}
} catch ( MissingObjectException e ) {
errors . getMissingObjects ( ) . add ( e . getObjectId ( ) ) ;
continue ;
}
ow . markStart ( tip ) ;
}
try {
ow . checkConnectivity ( ) ;
} catch ( MissingObjectException e ) {
errors . getMissingObjects ( ) . add ( e . getObjectId ( ) ) ;
}
} finally {
ctx . close ( ) ;
}
return errors ;
pm . endTask ( ) ;
}
/ * *