@ -60,6 +60,8 @@ import static org.junit.Assert.fail;
import java.io.File ;
import java.io.File ;
import java.io.IOException ;
import java.io.IOException ;
import java.util.ArrayList ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.List ;
import java.util.Map ;
import java.util.Map ;
import java.util.concurrent.atomic.AtomicInteger ;
import java.util.concurrent.atomic.AtomicInteger ;
import java.util.concurrent.atomic.AtomicReference ;
import java.util.concurrent.atomic.AtomicReference ;
@ -67,17 +69,20 @@ import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jgit.events.ListenerHandle ;
import org.eclipse.jgit.events.ListenerHandle ;
import org.eclipse.jgit.events.RefsChangedEvent ;
import org.eclipse.jgit.events.RefsChangedEvent ;
import org.eclipse.jgit.events.RefsChangedListener ;
import org.eclipse.jgit.events.RefsChangedListener ;
import org.eclipse.jgit.internal.storage.file.FileRepository ;
import org.eclipse.jgit.internal.storage.file.RefDirectory ;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase ;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase ;
import org.eclipse.jgit.junit.TestRepository ;
import org.eclipse.jgit.junit.TestRepository ;
import org.eclipse.jgit.lib.AnyObjectId ;
import org.eclipse.jgit.lib.AnyObjectId ;
import org.eclipse.jgit.lib.BatchRefUpdate ;
import org.eclipse.jgit.lib.NullProgressMonitor ;
import org.eclipse.jgit.lib.Ref ;
import org.eclipse.jgit.lib.Ref ;
import org.eclipse.jgit.lib.Ref.Storage ;
import org.eclipse.jgit.lib.Ref.Storage ;
import org.eclipse.jgit.lib.RefDatabase ;
import org.eclipse.jgit.lib.RefDatabase ;
import org.eclipse.jgit.lib.Repository ;
import org.eclipse.jgit.lib.Repository ;
import org.eclipse.jgit.revwalk.RevCommit ;
import org.eclipse.jgit.revwalk.RevCommit ;
import org.eclipse.jgit.revwalk.RevTag ;
import org.eclipse.jgit.revwalk.RevTag ;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.eclipse.jgit.transport.ReceiveCommand ;
import org.eclipse.jgit.transport.ReceiveCommand.Type ;
import org.junit.Before ;
import org.junit.Before ;
import org.junit.Test ;
import org.junit.Test ;
@ -1175,6 +1180,112 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase {
assertEquals ( 1 , changeCount . get ( ) ) ;
assertEquals ( 1 , changeCount . get ( ) ) ;
}
}
@Test
public void testBatchRefUpdateSimpleNoForce ( ) throws IOException {
writeLooseRef ( "refs/heads/master" , A ) ;
writeLooseRef ( "refs/heads/masters" , B ) ;
List < ReceiveCommand > commands = Arrays . asList (
newCommand ( A , B , "refs/heads/master" ,
ReceiveCommand . Type . UPDATE ) ,
newCommand ( B , A , "refs/heads/masters" ,
ReceiveCommand . Type . UPDATE_NONFASTFORWARD ) ) ;
BatchRefUpdate batchUpdate = refdir . newBatchUpdate ( ) ;
batchUpdate . addCommand ( commands ) ;
batchUpdate
. execute ( new RevWalk ( diskRepo ) , NullProgressMonitor . INSTANCE ) ;
Map < String , Ref > refs = refdir . getRefs ( RefDatabase . ALL ) ;
assertEquals ( ReceiveCommand . Result . OK , commands . get ( 0 ) . getResult ( ) ) ;
assertEquals ( ReceiveCommand . Result . REJECTED_NONFASTFORWARD , commands
. get ( 1 ) . getResult ( ) ) ;
assertEquals ( "[HEAD, refs/heads/master, refs/heads/masters]" , refs
. keySet ( ) . toString ( ) ) ;
assertEquals ( B . getId ( ) , refs . get ( "refs/heads/master" ) . getObjectId ( ) ) ;
assertEquals ( B . getId ( ) , refs . get ( "refs/heads/masters" ) . getObjectId ( ) ) ;
}
@Test
public void testBatchRefUpdateSimpleForce ( ) throws IOException {
writeLooseRef ( "refs/heads/master" , A ) ;
writeLooseRef ( "refs/heads/masters" , B ) ;
List < ReceiveCommand > commands = Arrays . asList (
newCommand ( A , B , "refs/heads/master" ,
ReceiveCommand . Type . UPDATE ) ,
newCommand ( B , A , "refs/heads/masters" ,
ReceiveCommand . Type . UPDATE_NONFASTFORWARD ) ) ;
BatchRefUpdate batchUpdate = refdir . newBatchUpdate ( ) ;
batchUpdate . setAllowNonFastForwards ( true ) ;
batchUpdate . addCommand ( commands ) ;
batchUpdate
. execute ( new RevWalk ( diskRepo ) , NullProgressMonitor . INSTANCE ) ;
Map < String , Ref > refs = refdir . getRefs ( RefDatabase . ALL ) ;
assertEquals ( ReceiveCommand . Result . OK , commands . get ( 0 ) . getResult ( ) ) ;
assertEquals ( ReceiveCommand . Result . OK , commands . get ( 1 ) . getResult ( ) ) ;
assertEquals ( "[HEAD, refs/heads/master, refs/heads/masters]" , refs
. keySet ( ) . toString ( ) ) ;
assertEquals ( B . getId ( ) , refs . get ( "refs/heads/master" ) . getObjectId ( ) ) ;
assertEquals ( A . getId ( ) , refs . get ( "refs/heads/masters" ) . getObjectId ( ) ) ;
}
@Test
public void testBatchRefUpdateConflict ( ) throws IOException {
writeLooseRef ( "refs/heads/master" , A ) ;
writeLooseRef ( "refs/heads/masters" , B ) ;
List < ReceiveCommand > commands = Arrays . asList (
newCommand ( A , B , "refs/heads/master" ,
ReceiveCommand . Type . UPDATE ) ,
newCommand ( null , A , "refs/heads/master/x" ,
ReceiveCommand . Type . CREATE ) ,
newCommand ( null , A , "refs/heads" , ReceiveCommand . Type . CREATE ) ) ;
BatchRefUpdate batchUpdate = refdir . newBatchUpdate ( ) ;
batchUpdate . setAllowNonFastForwards ( true ) ;
batchUpdate . addCommand ( commands ) ;
batchUpdate
. execute ( new RevWalk ( diskRepo ) , NullProgressMonitor . INSTANCE ) ;
Map < String , Ref > refs = refdir . getRefs ( RefDatabase . ALL ) ;
assertEquals ( ReceiveCommand . Result . OK , commands . get ( 0 ) . getResult ( ) ) ;
assertEquals ( ReceiveCommand . Result . LOCK_FAILURE , commands . get ( 1 )
. getResult ( ) ) ;
assertEquals ( ReceiveCommand . Result . LOCK_FAILURE , commands . get ( 2 )
. getResult ( ) ) ;
assertEquals ( "[HEAD, refs/heads/master, refs/heads/masters]" , refs
. keySet ( ) . toString ( ) ) ;
assertEquals ( B . getId ( ) , refs . get ( "refs/heads/master" ) . getObjectId ( ) ) ;
assertEquals ( B . getId ( ) , refs . get ( "refs/heads/masters" ) . getObjectId ( ) ) ;
}
@Test
public void testBatchRefUpdateConflictThanksToDelete ( ) throws IOException {
writeLooseRef ( "refs/heads/master" , A ) ;
writeLooseRef ( "refs/heads/masters" , B ) ;
List < ReceiveCommand > commands = Arrays . asList (
newCommand ( A , B , "refs/heads/master" ,
ReceiveCommand . Type . UPDATE ) ,
newCommand ( null , A , "refs/heads/masters/x" ,
ReceiveCommand . Type . CREATE ) ,
newCommand ( B , null , "refs/heads/masters" ,
ReceiveCommand . Type . DELETE ) ) ;
BatchRefUpdate batchUpdate = refdir . newBatchUpdate ( ) ;
batchUpdate . setAllowNonFastForwards ( true ) ;
batchUpdate . addCommand ( commands ) ;
batchUpdate
. execute ( new RevWalk ( diskRepo ) , NullProgressMonitor . INSTANCE ) ;
Map < String , Ref > refs = refdir . getRefs ( RefDatabase . ALL ) ;
assertEquals ( ReceiveCommand . Result . OK , commands . get ( 0 ) . getResult ( ) ) ;
assertEquals ( ReceiveCommand . Result . OK , commands . get ( 1 ) . getResult ( ) ) ;
assertEquals ( ReceiveCommand . Result . OK , commands . get ( 2 ) . getResult ( ) ) ;
assertEquals ( "[HEAD, refs/heads/master, refs/heads/masters/x]" , refs
. keySet ( ) . toString ( ) ) ;
assertEquals ( A . getId ( ) , refs . get ( "refs/heads/masters/x" ) . getObjectId ( ) ) ;
}
private static ReceiveCommand newCommand ( RevCommit a , RevCommit b ,
String string , Type update ) {
ReceiveCommand ret = new ReceiveCommand ( a ! = null ? a . getId ( ) : null ,
b ! = null ? b . getId ( ) : null , string , update ) ;
ret . setResult ( ReceiveCommand . Result . NOT_ATTEMPTED ) ;
return ret ;
}
private void writeLooseRef ( String name , AnyObjectId id ) throws IOException {
private void writeLooseRef ( String name , AnyObjectId id ) throws IOException {
writeLooseRef ( name , id . name ( ) + "\n" ) ;
writeLooseRef ( name , id . name ( ) + "\n" ) ;
}
}