@ -67,6 +67,10 @@ import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.errors.ConfigInvalidException ;
import org.eclipse.jgit.errors.ConfigInvalidException ;
import org.eclipse.jgit.errors.IncorrectObjectTypeException ;
import org.eclipse.jgit.errors.IncorrectObjectTypeException ;
import org.eclipse.jgit.errors.RevisionSyntaxException ;
import org.eclipse.jgit.errors.RevisionSyntaxException ;
import org.eclipse.jgit.revwalk.RevBlob ;
import org.eclipse.jgit.revwalk.RevCommit ;
import org.eclipse.jgit.revwalk.RevObject ;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.eclipse.jgit.util.FS ;
import org.eclipse.jgit.util.FS ;
import org.eclipse.jgit.util.IO ;
import org.eclipse.jgit.util.IO ;
import org.eclipse.jgit.util.RawParseUtils ;
import org.eclipse.jgit.util.RawParseUtils ;
@ -745,36 +749,37 @@ public class Repository {
*
*
* Currently supported is combinations of these .
* Currently supported is combinations of these .
* < ul >
* < ul >
* < li > SHA - 1 - a SHA - 1 < / li >
* < li > SHA - 1 - a SHA - 1 < / li >
* < li > refs / . . . - a ref name < / li >
* < li > refs / . . . - a ref name < / li >
* < li > ref ^ n - nth parent reference < / li >
* < li > ref ^ n - nth parent reference < / li >
* < li > ref ~ n - distance via parent reference < / li >
* < li > ref ~ n - distance via parent reference < / li >
* < li > ref @ { n } - nth version of ref < / li >
* < li > ref @ { n } - nth version of ref < / li >
* < li > ref ^ { tree } - tree references by ref < / li >
* < li > ref ^ { tree } - tree references by ref < / li >
* < li > ref ^ { commit } - commit references by ref < / li >
* < li > ref ^ { commit } - commit references by ref < / li >
* < / ul >
* < / ul >
*
*
* Not supported is
* Not supported is :
* < ul >
* < ul >
* < li > timestamps in reflogs , ref @ { full or relative timestamp } < / li >
* < li > timestamps in reflogs , ref @ { full or relative timestamp } < / li >
* < li > abbreviated SHA - 1 ' s < / li >
* < li > abbreviated SHA - 1 ' s < / li >
* < / ul >
* < / ul >
*
*
* @param revstr A git object references expression
* @param revstr
* A git object references expression
* @return an ObjectId or null if revstr can ' t be resolved to any ObjectId
* @return an ObjectId or null if revstr can ' t be resolved to any ObjectId
* @throws IOException on serious errors
* @throws IOException
* on serious errors
* /
* /
public ObjectId resolve ( final String revstr ) throws IOException {
public ObjectId resolve ( final String revstr ) throws IOException {
char [ ] rev = revstr . toCharArray ( ) ;
char [ ] rev = revstr . toCharArray ( ) ;
Object ref = null ;
Rev Object ref = null ;
ObjectId refId = null ;
RevWalk rw = new RevWalk ( this ) ;
for ( int i = 0 ; i < rev . length ; + + i ) {
for ( int i = 0 ; i < rev . length ; + + i ) {
switch ( rev [ i ] ) {
switch ( rev [ i ] ) {
case '^' :
case '^' :
if ( refId = = null ) {
if ( ref = = null ) {
String refstr = new String ( rev , 0 , i ) ;
ref = parseSimple ( rw , new String ( rev , 0 , i ) ) ;
refId = resolveSimple ( refstr ) ;
if ( ref = = null )
if ( refId = = null )
return null ;
return null ;
}
}
if ( i + 1 < rev . length ) {
if ( i + 1 < rev . length ) {
@ -790,19 +795,12 @@ public class Repository {
case '8' :
case '8' :
case '9' :
case '9' :
int j ;
int j ;
ref = mapObject ( refId , null ) ;
ref = rw . parseCommit ( ref ) ;
while ( ref instanceof Tag ) {
for ( j = i + 1 ; j < rev . length ; + + j ) {
Tag tag = ( Tag ) ref ;
refId = tag . getObjId ( ) ;
ref = mapObject ( refId , null ) ;
}
if ( ! ( ref instanceof Commit ) )
throw new IncorrectObjectTypeException ( refId , Constants . TYPE_COMMIT ) ;
for ( j = i + 1 ; j < rev . length ; + + j ) {
if ( ! Character . isDigit ( rev [ j ] ) )
if ( ! Character . isDigit ( rev [ j ] ) )
break ;
break ;
}
}
String parentnum = new String ( rev , i + 1 , j - i - 1 ) ;
String parentnum = new String ( rev , i + 1 , j - i - 1 ) ;
int pnum ;
int pnum ;
try {
try {
pnum = Integer . parseInt ( parentnum ) ;
pnum = Integer . parseInt ( parentnum ) ;
@ -812,123 +810,83 @@ public class Repository {
revstr ) ;
revstr ) ;
}
}
if ( pnum ! = 0 ) {
if ( pnum ! = 0 ) {
final ObjectId parents [ ] = ( ( Commit ) ref )
RevCommit commit = ( RevCommit ) ref ;
. getParentIds ( ) ;
if ( pnum > commit . getParentCount ( ) )
if ( pnum > parents . length )
ref = null ;
refId = null ;
else
else
refId = parents [ pnum - 1 ] ;
ref = commit . getParent ( pnum - 1 ) ;
}
}
i = j - 1 ;
i = j - 1 ;
break ;
break ;
case '{' :
case '{' :
int k ;
int k ;
String item = null ;
String item = null ;
for ( k = i + 2 ; k < rev . length ; + + k ) {
for ( k = i + 2 ; k < rev . length ; + + k ) {
if ( rev [ k ] = = '}' ) {
if ( rev [ k ] = = '}' ) {
item = new String ( rev , i + 2 , k - i - 2 ) ;
item = new String ( rev , i + 2 , k - i - 2 ) ;
break ;
break ;
}
}
}
}
i = k ;
i = k ;
if ( item ! = null )
if ( item ! = null )
if ( item . equals ( "tree" ) ) {
if ( item . equals ( "tree" ) ) {
ref = mapObject ( refId , null ) ;
ref = rw . parseTree ( ref ) ;
while ( ref instanceof Tag ) {
} else if ( item . equals ( "commit" ) ) {
Tag t = ( Tag ) ref ;
ref = rw . parseCommit ( ref ) ;
refId = t . getObjId ( ) ;
} else if ( item . equals ( "blob" ) ) {
ref = mapObject ( refId , null ) ;
ref = rw . peel ( ref ) ;
}
if ( ! ( ref instanceof RevBlob ) )
if ( ref instanceof Treeish )
throw new IncorrectObjectTypeException ( ref ,
refId = ( ( Treeish ) ref ) . getTreeId ( ) ;
Constants . TYPE_BLOB ) ;
else
} else if ( item . equals ( "" ) ) {
throw new IncorrectObjectTypeException ( refId , Constants . TYPE_TREE ) ;
ref = rw . peel ( ref ) ;
}
} else
else if ( item . equals ( "commit" ) ) {
ref = mapObject ( refId , null ) ;
while ( ref instanceof Tag ) {
Tag t = ( Tag ) ref ;
refId = t . getObjId ( ) ;
ref = mapObject ( refId , null ) ;
}
if ( ! ( ref instanceof Commit ) )
throw new IncorrectObjectTypeException ( refId , Constants . TYPE_COMMIT ) ;
}
else if ( item . equals ( "blob" ) ) {
ref = mapObject ( refId , null ) ;
while ( ref instanceof Tag ) {
Tag t = ( Tag ) ref ;
refId = t . getObjId ( ) ;
ref = mapObject ( refId , null ) ;
}
if ( ! ( ref instanceof byte [ ] ) )
throw new IncorrectObjectTypeException ( refId , Constants . TYPE_BLOB ) ;
}
else if ( item . equals ( "" ) ) {
ref = mapObject ( refId , null ) ;
while ( ref instanceof Tag ) {
Tag t = ( Tag ) ref ;
refId = t . getObjId ( ) ;
ref = mapObject ( refId , null ) ;
}
}
else
throw new RevisionSyntaxException ( revstr ) ;
throw new RevisionSyntaxException ( revstr ) ;
else
else
throw new RevisionSyntaxException ( revstr ) ;
throw new RevisionSyntaxException ( revstr ) ;
break ;
break ;
default :
default :
ref = mapObject ( refId , null ) ;
ref = rw . parseAny ( ref ) ;
if ( ref instanceof Commit ) {
if ( ref instanceof RevCommit ) {
final ObjectId parents [ ] = ( ( Commit ) ref )
RevCommit commit = ( ( RevCommit ) ref ) ;
. getParentIds ( ) ;
if ( commit . getParentCount ( ) = = 0 )
if ( parents . length = = 0 )
ref = null ;
refId = null ;
else
else
refId = parents [ 0 ] ;
ref = commit . getParent ( 0 ) ;
} else
} else
throw new IncorrectObjectTypeException ( refId , Constants . TYPE_COMMIT ) ;
throw new IncorrectObjectTypeException ( ref ,
Constants . TYPE_COMMIT ) ;
}
}
} else {
} else {
ref = mapObject ( refId , null ) ;
ref = rw . peel ( ref ) ;
while ( ref instanceof Tag ) {
if ( ref instanceof RevCommit ) {
Tag tag = ( Tag ) ref ;
RevCommit commit = ( ( RevCommit ) ref ) ;
refId = tag . getObjId ( ) ;
if ( commit . getParentCount ( ) = = 0 )
ref = mapObject ( refId , null ) ;
ref = null ;
}
if ( ref instanceof Commit ) {
final ObjectId parents [ ] = ( ( Commit ) ref )
. getParentIds ( ) ;
if ( parents . length = = 0 )
refId = null ;
else
else
refId = parents [ 0 ] ;
ref = commit . getParent ( 0 ) ;
} else
} else
throw new IncorrectObjectTypeException ( refId , Constants . TYPE_COMMIT ) ;
throw new IncorrectObjectTypeException ( ref ,
Constants . TYPE_COMMIT ) ;
}
}
break ;
break ;
case '~' :
case '~' :
if ( ref = = null ) {
if ( ref = = null ) {
String refstr = new String ( rev , 0 , i ) ;
ref = parseSimple ( rw , new String ( rev , 0 , i ) ) ;
refId = resolveSimple ( refstr ) ;
if ( ref = = null )
if ( refId = = null )
return null ;
return null ;
ref = mapObject ( refId , null ) ;
}
while ( ref instanceof Tag ) {
Tag tag = ( Tag ) ref ;
refId = tag . getObjId ( ) ;
ref = mapObject ( refId , null ) ;
}
}
if ( ! ( ref instanceof Commit ) )
ref = rw . peel ( ref ) ;
throw new IncorrectObjectTypeException ( refId , Constants . TYPE_COMMIT ) ;
if ( ! ( ref instanceof RevCommit ) )
throw new IncorrectObjectTypeException ( ref ,
Constants . TYPE_COMMIT ) ;
int l ;
int l ;
for ( l = i + 1 ; l < rev . length ; + + l ) {
for ( l = i + 1 ; l < rev . length ; + + l ) {
if ( ! Character . isDigit ( rev [ l ] ) )
if ( ! Character . isDigit ( rev [ l ] ) )
break ;
break ;
}
}
String distnum = new String ( rev , i + 1 , l - i - 1 ) ;
String distnum = new String ( rev , i + 1 , l - i - 1 ) ;
int dist ;
int dist ;
try {
try {
dist = Integer . parseInt ( distnum ) ;
dist = Integer . parseInt ( distnum ) ;
@ -937,13 +895,14 @@ public class Repository {
JGitText . get ( ) . invalidAncestryLength , revstr ) ;
JGitText . get ( ) . invalidAncestryLength , revstr ) ;
}
}
while ( dist > 0 ) {
while ( dist > 0 ) {
final ObjectId [ ] parents = ( ( Commit ) ref ) . getParentIds ( ) ;
RevCommit commit = ( Rev Commit) ref ;
if ( parents . length = = 0 ) {
if ( commit . getParentCount ( ) = = 0 ) {
refId = null ;
ref = null ;
break ;
break ;
}
}
refId = parents [ 0 ] ;
commit = commit . getParent ( 0 ) ;
ref = mapCommit ( refId ) ;
rw . parseHeaders ( commit ) ;
ref = commit ;
- - dist ;
- - dist ;
}
}
i = l - 1 ;
i = l - 1 ;
@ -951,30 +910,35 @@ public class Repository {
case '@' :
case '@' :
int m ;
int m ;
String time = null ;
String time = null ;
for ( m = i + 2 ; m < rev . length ; + + m ) {
for ( m = i + 2 ; m < rev . length ; + + m ) {
if ( rev [ m ] = = '}' ) {
if ( rev [ m ] = = '}' ) {
time = new String ( rev , i + 2 , m - i - 2 ) ;
time = new String ( rev , i + 2 , m - i - 2 ) ;
break ;
break ;
}
}
}
}
if ( time ! = null )
if ( time ! = null )
throw new RevisionSyntaxException ( JGitText . get ( ) . reflogsNotYetSupportedByRevisionParser , revstr ) ;
throw new RevisionSyntaxException (
JGitText . get ( ) . reflogsNotYetSupportedByRevisionParser ,
revstr ) ;
i = m - 1 ;
i = m - 1 ;
break ;
break ;
default :
default :
if ( refId ! = null )
if ( ref ! = null )
throw new RevisionSyntaxException ( revstr ) ;
throw new RevisionSyntaxException ( revstr ) ;
}
}
}
}
if ( refId = = null )
return ref ! = null ? ref . copy ( ) : resolveSimple ( revstr ) ;
refId = resolveSimple ( revstr ) ;
}
return refId ;
private RevObject parseSimple ( RevWalk rw , String revstr ) throws IOException {
ObjectId id = resolveSimple ( revstr ) ;
return id ! = null ? rw . parseAny ( id ) : null ;
}
}
private ObjectId resolveSimple ( final String revstr ) throws IOException {
private ObjectId resolveSimple ( final String revstr ) throws IOException {
if ( ObjectId . isId ( revstr ) )
if ( ObjectId . isId ( revstr ) )
return ObjectId . fromString ( revstr ) ;
return ObjectId . fromString ( revstr ) ;
final Ref r = refs . getRef ( revstr ) ;
final Ref r = getRefDatabase ( ) . getRef ( revstr ) ;
return r ! = null ? r . getObjectId ( ) : null ;
return r ! = null ? r . getObjectId ( ) : null ;
}
}