@ -1,5 +1,5 @@
/ *
/ *
* Copyright ( C ) 2011 - 2012 , Chris Aniszczyk < caniszczyk @gmail.com >
* Copyright ( C ) 2011 - 2013 , Chris Aniszczyk < caniszczyk @gmail.com >
* and other copyright owners as documented in the project ' s IP log .
* and other copyright owners as documented in the project ' s IP log .
*
*
* This program and the accompanying materials are made available
* This program and the accompanying materials are made available
@ -67,6 +67,7 @@ import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.eclipse.jgit.treewalk.AbstractTreeIterator ;
import org.eclipse.jgit.treewalk.AbstractTreeIterator ;
import org.eclipse.jgit.treewalk.CanonicalTreeParser ;
import org.eclipse.jgit.treewalk.CanonicalTreeParser ;
import org.eclipse.jgit.treewalk.EmptyTreeIterator ;
import org.eclipse.jgit.treewalk.TreeWalk ;
import org.eclipse.jgit.treewalk.TreeWalk ;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup ;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup ;
@ -114,7 +115,9 @@ public class ResetCommand extends GitCommand<Ref> {
KEEP // TODO not implemented yet
KEEP // TODO not implemented yet
}
}
private String ref = Constants . HEAD ;
// We need to be able to distinguish whether the caller set the ref
// explicitly or not, so we apply the default (HEAD) only later.
private String ref = null ;
private ResetType mode ;
private ResetType mode ;
@ -139,9 +142,6 @@ public class ResetCommand extends GitCommand<Ref> {
public Ref call ( ) throws GitAPIException , CheckoutConflictException {
public Ref call ( ) throws GitAPIException , CheckoutConflictException {
checkCallable ( ) ;
checkCallable ( ) ;
Ref r ;
RevCommit commit ;
try {
try {
RepositoryState state = repo . getRepositoryState ( ) ;
RepositoryState state = repo . getRepositoryState ( ) ;
final boolean merging = state . equals ( RepositoryState . MERGING )
final boolean merging = state . equals ( RepositoryState . MERGING )
@ -152,61 +152,55 @@ public class ResetCommand extends GitCommand<Ref> {
final boolean reverting = state . equals ( RepositoryState . REVERTING )
final boolean reverting = state . equals ( RepositoryState . REVERTING )
| | state . equals ( RepositoryState . REVERTING_RESOLVED ) ;
| | state . equals ( RepositoryState . REVERTING_RESOLVED ) ;
// resolve the ref to a commit
final ObjectId commitId = resolveRefToCommitId ( ) ;
final ObjectId commitId ;
// When ref is explicitly specified, it has to resolve
try {
if ( ref ! = null & & commitId = = null ) {
commitId = repo . resolve ( ref + "^{commit}" ) ; //$NON-NLS-1$
// @TODO throw an InvalidRefNameException. We can't do that
if ( commitId = = null ) {
// now because this would break the API
// @TODO throw an InvalidRefNameException. We can't do that
throw new JGitInternalException ( "Invalid ref " + ref
// now because this would break the API
+ " specified" ) ;
throw new JGitInternalException ( "Invalid ref " + ref
+ " specified" ) ;
}
} catch ( IOException e ) {
throw new JGitInternalException (
MessageFormat . format ( JGitText . get ( ) . cannotRead , ref ) ,
e ) ;
}
RevWalk rw = new RevWalk ( repo ) ;
try {
commit = rw . parseCommit ( commitId ) ;
} catch ( IOException e ) {
throw new JGitInternalException (
MessageFormat . format (
JGitText . get ( ) . cannotReadCommit , commitId . toString ( ) ) ,
e ) ;
} finally {
rw . release ( ) ;
}
}
final ObjectId commitTree ;
if ( commitId ! = null )
commitTree = parseCommit ( commitId ) . getTree ( ) ;
else
commitTree = null ;
if ( ! filepaths . isEmpty ( ) ) {
if ( ! filepaths . isEmpty ( ) ) {
// reset [commit] -- paths
// reset [commit] -- paths
resetIndexForPaths ( commit ) ;
resetIndexForPaths ( commitTree ) ;
setCallable ( false ) ;
setCallable ( false ) ;
return repo . getRef ( Constants . HEAD ) ;
return repo . getRef ( Constants . HEAD ) ;
}
}
// write the ref
final Ref result ;
final RefUpdate ru = repo . updateRef ( Constants . HEAD ) ;
if ( commitId ! = null ) {
ru . setNewObjectId ( commitId ) ;
// write the ref
final RefUpdate ru = repo . updateRef ( Constants . HEAD ) ;
String refName = Repository . shortenRefName ( ref ) ;
ru . setNewObjectId ( commitId ) ;
String message = refName + ": updating " + Constants . HEAD ; //$NON-NLS-1$
ru . setRefLogMessage ( message , false ) ;
String refName = Repository . shortenRefName ( getRefOrHEAD ( ) ) ;
if ( ru . forceUpdate ( ) = = RefUpdate . Result . LOCK_FAILURE )
String message = refName + ": updating " + Constants . HEAD ; //$NON-NLS-1$
throw new JGitInternalException ( MessageFormat . format (
ru . setRefLogMessage ( message , false ) ;
JGitText . get ( ) . cannotLock , ru . getName ( ) ) ) ;
if ( ru . forceUpdate ( ) = = RefUpdate . Result . LOCK_FAILURE )
throw new JGitInternalException ( MessageFormat . format (
ObjectId origHead = ru . getOldObjectId ( ) ;
JGitText . get ( ) . cannotLock , ru . getName ( ) ) ) ;
if ( origHead ! = null )
repo . writeOrigHead ( origHead ) ;
ObjectId origHead = ru . getOldObjectId ( ) ;
if ( origHead ! = null )
repo . writeOrigHead ( origHead ) ;
result = ru . getRef ( ) ;
} else {
result = repo . getRef ( Constants . HEAD ) ;
}
switch ( mode ) {
switch ( mode ) {
case HARD :
case HARD :
checkoutIndex ( commit ) ;
checkoutIndex ( commitTree ) ;
break ;
break ;
case MIXED :
case MIXED :
resetIndex ( commit ) ;
resetIndex ( commitTree ) ;
break ;
break ;
case SOFT : // do nothing, only the ref was changed
case SOFT : // do nothing, only the ref was changed
break ;
break ;
@ -228,19 +222,41 @@ public class ResetCommand extends GitCommand<Ref> {
}
}
setCallable ( false ) ;
setCallable ( false ) ;
r = ru . getRef ( ) ;
return result ;
} catch ( IOException e ) {
} catch ( IOException e ) {
throw new JGitInternalException (
throw new JGitInternalException (
JGitText . get ( ) . exceptionCaughtDuringExecutionOfResetCommand ,
JGitText . get ( ) . exceptionCaughtDuringExecutionOfResetCommand ,
e ) ;
e ) ;
}
}
}
private RevCommit parseCommit ( final ObjectId commitId ) {
RevCommit commit ;
RevWalk rw = new RevWalk ( repo ) ;
try {
commit = rw . parseCommit ( commitId ) ;
} catch ( IOException e ) {
throw new JGitInternalException ( MessageFormat . format (
JGitText . get ( ) . cannotReadCommit , commitId . toString ( ) ) , e ) ;
} finally {
rw . release ( ) ;
}
return commit ;
}
return r ;
private ObjectId resolveRefToCommitId ( ) {
try {
return repo . resolve ( getRefOrHEAD ( ) + "^{commit}" ) ; //$NON-NLS-1$
} catch ( IOException e ) {
throw new JGitInternalException (
MessageFormat . format ( JGitText . get ( ) . cannotRead , getRefOrHEAD ( ) ) ,
e ) ;
}
}
}
/ * *
/ * *
* @param ref
* @param ref
* the ref to reset to
* the ref to reset to , defaults to HEAD if not specified
* @return this instance
* @return this instance
* /
* /
public ResetCommand setRef ( String ref ) {
public ResetCommand setRef ( String ref ) {
@ -276,7 +292,14 @@ public class ResetCommand extends GitCommand<Ref> {
return this ;
return this ;
}
}
private void resetIndexForPaths ( RevCommit commit ) {
private String getRefOrHEAD ( ) {
if ( ref ! = null )
return ref ;
else
return Constants . HEAD ;
}
private void resetIndexForPaths ( ObjectId commitTree ) {
DirCache dc = null ;
DirCache dc = null ;
try {
try {
dc = repo . lockDirCache ( ) ;
dc = repo . lockDirCache ( ) ;
@ -284,7 +307,10 @@ public class ResetCommand extends GitCommand<Ref> {
final TreeWalk tw = new TreeWalk ( repo ) ;
final TreeWalk tw = new TreeWalk ( repo ) ;
tw . addTree ( new DirCacheBuildIterator ( builder ) ) ;
tw . addTree ( new DirCacheBuildIterator ( builder ) ) ;
tw . addTree ( commit . getTree ( ) ) ;
if ( commitTree ! = null )
tw . addTree ( commitTree ) ;
else
tw . addTree ( new EmptyTreeIterator ( ) ) ;
tw . setFilter ( PathFilterGroup . createFromStrings ( filepaths ) ) ;
tw . setFilter ( PathFilterGroup . createFromStrings ( filepaths ) ) ;
tw . setRecursive ( true ) ;
tw . setRecursive ( true ) ;
@ -310,14 +336,17 @@ public class ResetCommand extends GitCommand<Ref> {
}
}
}
}
private void resetIndex ( RevCommit commit ) throws IOException {
private void resetIndex ( ObjectId commitTree ) throws IOException {
DirCache dc = repo . lockDirCache ( ) ;
DirCache dc = repo . lockDirCache ( ) ;
TreeWalk walk = null ;
TreeWalk walk = null ;
try {
try {
DirCacheBuilder builder = dc . builder ( ) ;
DirCacheBuilder builder = dc . builder ( ) ;
walk = new TreeWalk ( repo ) ;
walk = new TreeWalk ( repo ) ;
walk . addTree ( commit . getTree ( ) ) ;
if ( commitTree ! = null )
walk . addTree ( commitTree ) ;
else
walk . addTree ( new EmptyTreeIterator ( ) ) ;
walk . addTree ( new DirCacheIterator ( dc ) ) ;
walk . addTree ( new DirCacheIterator ( dc ) ) ;
walk . setRecursive ( true ) ;
walk . setRecursive ( true ) ;
@ -352,12 +381,12 @@ public class ResetCommand extends GitCommand<Ref> {
}
}
}
}
private void checkoutIndex ( RevCommit commit ) throws IOException ,
private void checkoutIndex ( ObjectId commitTree ) throws IOException ,
GitAPIException {
GitAPIException {
DirCache dc = repo . lockDirCache ( ) ;
DirCache dc = repo . lockDirCache ( ) ;
try {
try {
DirCacheCheckout checkout = new DirCacheCheckout ( repo , dc ,
DirCacheCheckout checkout = new DirCacheCheckout ( repo , dc ,
commit . get Tree( ) ) ;
commitTree ) ;
checkout . setFailOnConflict ( false ) ;
checkout . setFailOnConflict ( false ) ;
try {
try {
checkout . checkout ( ) ;
checkout . checkout ( ) ;