@ -43,15 +43,21 @@
package org.eclipse.jgit.pgm ;
package org.eclipse.jgit.pgm ;
import static org.junit.Assert.assertArrayEquals ;
import static org.junit.Assert.assertArrayEquals ;
import static org.junit.Assert.assertNotNull ;
import java.io.File ;
import java.io.File ;
import java.util.List ;
import org.eclipse.jgit.api.Git ;
import org.eclipse.jgit.api.Git ;
import org.eclipse.jgit.api.errors.CheckoutConflictException ;
import org.eclipse.jgit.diff.DiffEntry ;
import org.eclipse.jgit.lib.CLIRepositoryTestCase ;
import org.eclipse.jgit.lib.CLIRepositoryTestCase ;
import org.eclipse.jgit.lib.FileMode ;
import org.eclipse.jgit.lib.FileMode ;
import org.eclipse.jgit.lib.Ref ;
import org.eclipse.jgit.lib.Ref ;
import org.eclipse.jgit.revwalk.RevCommit ;
import org.eclipse.jgit.treewalk.FileTreeIterator ;
import org.eclipse.jgit.treewalk.FileTreeIterator ;
import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry ;
import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry ;
import org.eclipse.jgit.treewalk.TreeWalk ;
import org.eclipse.jgit.util.FileUtils ;
import org.eclipse.jgit.util.FileUtils ;
import org.junit.Assert ;
import org.junit.Assert ;
import org.junit.Test ;
import org.junit.Test ;
@ -150,6 +156,7 @@ public class CheckoutTest extends CLIRepositoryTestCase {
* < li > Delete file 'a' in the working tree
* < li > Delete file 'a' in the working tree
* < li > Checkout branch '1'
* < li > Checkout branch '1'
* < / ol >
* < / ol >
* < p >
* The working tree should contain 'a' with FileMode . REGULAR_FILE after the
* The working tree should contain 'a' with FileMode . REGULAR_FILE after the
* checkout .
* checkout .
*
*
@ -181,6 +188,359 @@ public class CheckoutTest extends CLIRepositoryTestCase {
assertEquals ( "Hello world a" , read ( fileA ) ) ;
assertEquals ( "Hello world a" , read ( fileA ) ) ;
}
}
/ * *
* Steps :
* < ol >
* < li > Add file 'b'
* < li > Commit
* < li > Create branch '1'
* < li > Add folder 'a'
* < li > Commit
* < li > Replace folder 'a' by file 'a' in the working tree
* < li > Checkout branch '1'
* < / ol >
* < p >
* The working tree should contain 'a' with FileMode . REGULAR_FILE after the
* checkout .
*
* @throws Exception
* /
@Test
public void fileModeTestMissingThenFolderWithFileInWorkingTree ( )
throws Exception {
Git git = new Git ( db ) ;
writeTrashFile ( "b" , "Hello world b" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add file b" ) . call ( ) ;
Ref branch_1 = git . branchCreate ( ) . setName ( "branch_1" ) . call ( ) ;
File folderA = new File ( db . getWorkTree ( ) , "a" ) ;
FileUtils . mkdirs ( folderA ) ;
writeTrashFile ( "a/c" , "Hello world c" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add folder a" ) . call ( ) ;
FileEntry entry = new FileTreeIterator . FileEntry ( new File (
db . getWorkTree ( ) , "a" ) , db . getFS ( ) ) ;
assertEquals ( FileMode . TREE , entry . getMode ( ) ) ;
FileUtils . delete ( folderA , FileUtils . RECURSIVE ) ;
writeTrashFile ( "a" , "b" ) ;
entry = new FileTreeIterator . FileEntry ( new File ( db . getWorkTree ( ) , "a" ) ,
db . getFS ( ) ) ;
assertEquals ( FileMode . REGULAR_FILE , entry . getMode ( ) ) ;
git . checkout ( ) . setName ( branch_1 . getName ( ) ) . call ( ) ;
entry = new FileTreeIterator . FileEntry ( new File ( db . getWorkTree ( ) , "a" ) ,
db . getFS ( ) ) ;
assertEquals ( FileMode . REGULAR_FILE , entry . getMode ( ) ) ;
}
/ * *
* Steps :
* < ol >
* < li > Add file 'a'
* < li > Commit
* < li > Create branch '1'
* < li > Replace file 'a' by folder 'a'
* < li > Commit
* < li > Delete folder 'a' in the working tree
* < li > Checkout branch '1'
* < / ol >
* < p >
* The working tree should contain 'a' with FileMode . REGULAR_FILE after the
* checkout .
*
* @throws Exception
* /
@Test
public void fileModeTestFolderWithMissingInWorkingTree ( ) throws Exception {
Git git = new Git ( db ) ;
writeTrashFile ( "b" , "Hello world b" ) ;
writeTrashFile ( "a" , "b" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add file b & file a" ) . call ( ) ;
Ref branch_1 = git . branchCreate ( ) . setName ( "branch_1" ) . call ( ) ;
git . rm ( ) . addFilepattern ( "a" ) . call ( ) ;
File folderA = new File ( db . getWorkTree ( ) , "a" ) ;
FileUtils . mkdirs ( folderA ) ;
writeTrashFile ( "a/c" , "Hello world c" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add folder a" ) . call ( ) ;
FileEntry entry = new FileTreeIterator . FileEntry ( new File (
db . getWorkTree ( ) , "a" ) , db . getFS ( ) ) ;
assertEquals ( FileMode . TREE , entry . getMode ( ) ) ;
FileUtils . delete ( folderA , FileUtils . RECURSIVE ) ;
git . checkout ( ) . setName ( branch_1 . getName ( ) ) . call ( ) ;
entry = new FileTreeIterator . FileEntry ( new File ( db . getWorkTree ( ) , "a" ) ,
db . getFS ( ) ) ;
assertEquals ( FileMode . REGULAR_FILE , entry . getMode ( ) ) ;
}
/ * *
* Steps :
* < ol >
* < li > Add file 'a'
* < li > Commit
* < li > Create branch '1'
* < li > Delete file 'a'
* < li > Commit
* < li > Add folder 'a' in the working tree
* < li > Checkout branch '1'
* < / ol >
* < p >
* The checkout command should raise an error . The conflicting paths are 'a'
* and ' a / c ' .
*
* @throws Exception
* /
@Test
public void fileModeTestMissingWithFolderInWorkingTree ( ) throws Exception {
Git git = new Git ( db ) ;
writeTrashFile ( "b" , "Hello world b" ) ;
writeTrashFile ( "a" , "b" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add file b & file a" ) . call ( ) ;
Ref branch_1 = git . branchCreate ( ) . setName ( "branch_1" ) . call ( ) ;
git . rm ( ) . addFilepattern ( "a" ) . call ( ) ;
git . commit ( ) . setMessage ( "delete file a" ) . call ( ) ;
FileUtils . mkdirs ( new File ( db . getWorkTree ( ) , "a" ) ) ;
writeTrashFile ( "a/c" , "Hello world c" ) ;
FileEntry entry = new FileTreeIterator . FileEntry ( new File (
db . getWorkTree ( ) , "a" ) , db . getFS ( ) ) ;
assertEquals ( FileMode . TREE , entry . getMode ( ) ) ;
CheckoutConflictException exception = null ;
try {
git . checkout ( ) . setName ( branch_1 . getName ( ) ) . call ( ) ;
} catch ( CheckoutConflictException e ) {
exception = e ;
}
assertNotNull ( exception ) ;
assertEquals ( 2 , exception . getConflictingPaths ( ) . size ( ) ) ;
assertEquals ( "a" , exception . getConflictingPaths ( ) . get ( 0 ) ) ;
assertEquals ( "a/c" , exception . getConflictingPaths ( ) . get ( 1 ) ) ;
}
/ * *
* Steps :
* < ol >
* < li > Add folder 'a'
* < li > Commit
* < li > Create branch '1'
* < li > Delete folder 'a'
* < li > Commit
* < li > Add file 'a' in the working tree
* < li > Checkout branch '1'
* < / ol >
* < p >
* The checkout command should raise an error . The conflicting path is 'a' .
*
* @throws Exception
* /
@Test
public void fileModeTestFolderThenMissingWithFileInWorkingTree ( )
throws Exception {
Git git = new Git ( db ) ;
FileUtils . mkdirs ( new File ( db . getWorkTree ( ) , "a" ) ) ;
writeTrashFile ( "a/c" , "Hello world c" ) ;
writeTrashFile ( "b" , "Hello world b" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
RevCommit commit1 = git . commit ( ) . setMessage ( "add folder a & file b" )
. call ( ) ;
Ref branch_1 = git . branchCreate ( ) . setName ( "branch_1" ) . call ( ) ;
git . rm ( ) . addFilepattern ( "a" ) . call ( ) ;
RevCommit commit2 = git . commit ( ) . setMessage ( "delete folder a" ) . call ( ) ;
TreeWalk tw = new TreeWalk ( db ) ;
tw . addTree ( commit1 . getTree ( ) ) ;
tw . addTree ( commit2 . getTree ( ) ) ;
List < DiffEntry > scan = DiffEntry . scan ( tw ) ;
assertEquals ( 1 , scan . size ( ) ) ;
assertEquals ( FileMode . MISSING , scan . get ( 0 ) . getNewMode ( ) ) ;
assertEquals ( FileMode . TREE , scan . get ( 0 ) . getOldMode ( ) ) ;
writeTrashFile ( "a" , "b" ) ;
FileEntry entry = new FileTreeIterator . FileEntry ( new File (
db . getWorkTree ( ) , "a" ) , db . getFS ( ) ) ;
assertEquals ( FileMode . REGULAR_FILE , entry . getMode ( ) ) ;
CheckoutConflictException exception = null ;
try {
git . checkout ( ) . setName ( branch_1 . getName ( ) ) . call ( ) ;
} catch ( CheckoutConflictException e ) {
exception = e ;
}
assertNotNull ( exception ) ;
assertEquals ( 1 , exception . getConflictingPaths ( ) . size ( ) ) ;
assertEquals ( "a" , exception . getConflictingPaths ( ) . get ( 0 ) ) ;
}
/ * *
* Steps :
* < ol >
* < li > Add folder 'a'
* < li > Commit
* < li > Create branch '1'
* < li > Replace folder 'a' by file 'a'
* < li > Commit
* < li > Delete file 'a' in the working tree
* < li > Checkout branch '1'
* < / ol >
* < p >
* The working tree should contain 'a' with FileMode . TREE after the
* checkout .
*
* @throws Exception
* /
@Test
public void fileModeTestFolderThenFileWithMissingInWorkingTree ( )
throws Exception {
Git git = new Git ( db ) ;
FileUtils . mkdirs ( new File ( db . getWorkTree ( ) , "a" ) ) ;
writeTrashFile ( "a/c" , "Hello world c" ) ;
writeTrashFile ( "b" , "Hello world b" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add folder a & file b" ) . call ( ) ;
Ref branch_1 = git . branchCreate ( ) . setName ( "branch_1" ) . call ( ) ;
git . rm ( ) . addFilepattern ( "a" ) . call ( ) ;
File fileA = new File ( db . getWorkTree ( ) , "a" ) ;
writeTrashFile ( "a" , "b" ) ;
git . add ( ) . addFilepattern ( "a" ) . call ( ) ;
git . commit ( ) . setMessage ( "add file a" ) . call ( ) ;
FileEntry entry = new FileTreeIterator . FileEntry ( new File (
db . getWorkTree ( ) , "a" ) , db . getFS ( ) ) ;
assertEquals ( FileMode . REGULAR_FILE , entry . getMode ( ) ) ;
FileUtils . delete ( fileA ) ;
git . checkout ( ) . setName ( branch_1 . getName ( ) ) . call ( ) ;
entry = new FileTreeIterator . FileEntry ( new File ( db . getWorkTree ( ) , "a" ) ,
db . getFS ( ) ) ;
assertEquals ( FileMode . TREE , entry . getMode ( ) ) ;
}
/ * *
* Steps :
* < ol >
* < li > Add file 'a'
* < li > Commit
* < li > Create branch '1'
* < li > Modify file 'a'
* < li > Commit
* < li > Delete file 'a' & replace by folder 'a' in the working tree & index
* < li > Checkout branch '1'
* < / ol >
* < p >
* The checkout command should raise an error . The conflicting path is 'a' .
*
* @throws Exception
* /
@Test
public void fileModeTestFileThenFileWithFolderInIndex ( ) throws Exception {
Git git = new Git ( db ) ;
writeTrashFile ( "a" , "Hello world a" ) ;
writeTrashFile ( "b" , "Hello world b" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add files a & b" ) . call ( ) ;
Ref branch_1 = git . branchCreate ( ) . setName ( "branch_1" ) . call ( ) ;
writeTrashFile ( "a" , "b" ) ;
git . add ( ) . addFilepattern ( "a" ) . call ( ) ;
git . commit ( ) . setMessage ( "add file a" ) . call ( ) ;
FileEntry entry = new FileTreeIterator . FileEntry ( new File (
db . getWorkTree ( ) , "a" ) , db . getFS ( ) ) ;
assertEquals ( FileMode . REGULAR_FILE , entry . getMode ( ) ) ;
git . rm ( ) . addFilepattern ( "a" ) . call ( ) ;
FileUtils . mkdirs ( new File ( db . getWorkTree ( ) , "a" ) ) ;
writeTrashFile ( "a/c" , "Hello world c" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
entry = new FileTreeIterator . FileEntry ( new File ( db . getWorkTree ( ) , "a" ) ,
db . getFS ( ) ) ;
assertEquals ( FileMode . TREE , entry . getMode ( ) ) ;
CheckoutConflictException exception = null ;
try {
git . checkout ( ) . setName ( branch_1 . getName ( ) ) . call ( ) ;
} catch ( CheckoutConflictException e ) {
exception = e ;
}
assertNotNull ( exception ) ;
assertEquals ( 1 , exception . getConflictingPaths ( ) . size ( ) ) ;
assertEquals ( "a" , exception . getConflictingPaths ( ) . get ( 0 ) ) ;
}
/ * *
* Steps :
* < ol >
* < li > Add file 'a'
* < li > Commit
* < li > Create branch '1'
* < li > Modify file 'a'
* < li > Commit
* < li > Delete file 'a' & replace by folder 'a' in the working tree & index
* < li > Checkout branch '1'
* < / ol >
* < p >
* The checkout command should raise an error . The conflicting paths are 'a'
* and ' a / c ' .
*
* @throws Exception
* /
@Test
public void fileModeTestFileWithFolderInIndex ( ) throws Exception {
Git git = new Git ( db ) ;
writeTrashFile ( "b" , "Hello world b" ) ;
writeTrashFile ( "a" , "b" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
git . commit ( ) . setMessage ( "add file b & file a" ) . call ( ) ;
Ref branch_1 = git . branchCreate ( ) . setName ( "branch_1" ) . call ( ) ;
git . rm ( ) . addFilepattern ( "a" ) . call ( ) ;
writeTrashFile ( "a" , "Hello world a" ) ;
git . add ( ) . addFilepattern ( "a" ) . call ( ) ;
git . commit ( ) . setMessage ( "add file a" ) . call ( ) ;
FileEntry entry = new FileTreeIterator . FileEntry ( new File (
db . getWorkTree ( ) , "a" ) , db . getFS ( ) ) ;
assertEquals ( FileMode . REGULAR_FILE , entry . getMode ( ) ) ;
git . rm ( ) . addFilepattern ( "a" ) . call ( ) ;
FileUtils . mkdirs ( new File ( db . getWorkTree ( ) , "a" ) ) ;
writeTrashFile ( "a/c" , "Hello world c" ) ;
git . add ( ) . addFilepattern ( "." ) . call ( ) ;
entry = new FileTreeIterator . FileEntry ( new File ( db . getWorkTree ( ) , "a" ) ,
db . getFS ( ) ) ;
assertEquals ( FileMode . TREE , entry . getMode ( ) ) ;
CheckoutConflictException exception = null ;
try {
git . checkout ( ) . setName ( branch_1 . getName ( ) ) . call ( ) ;
} catch ( CheckoutConflictException e ) {
exception = e ;
}
assertNotNull ( exception ) ;
assertEquals ( 1 , exception . getConflictingPaths ( ) . size ( ) ) ;
assertEquals ( "a" , exception . getConflictingPaths ( ) . get ( 0 ) ) ;
// TODO: ideally we'd like to get two paths from this exception
// assertEquals(2, exception.getConflictingPaths().size());
// assertEquals("a", exception.getConflictingPaths().get(0));
// assertEquals("a/c", exception.getConflictingPaths().get(1));
}
static private void assertEquals ( Object expected , Object actual ) {
static private void assertEquals ( Object expected , Object actual ) {
Assert . assertEquals ( expected , actual ) ;
Assert . assertEquals ( expected , actual ) ;
}
}