Last active
October 11, 2020 07:11
-
-
Save rherrmann/02d8d4fe81bb60d9049e to your computer and use it in GitHub Desktop.
'Learning Tests' that use the JGit API to explore the internals of Git commits: http://www.codeaffine.com/2014/10/20/git-internals/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************************************************** | |
* Copyright (c) 2014 Rüdiger Herrmann | |
* All rights reserved. This program and the accompanying materials are made available under the | |
* terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* Rüdiger Herrmann - initial API and implementation | |
**************************************************************************************************/ | |
package com.codeaffine.jgit; | |
import static org.junit.Assert.assertArrayEquals; | |
import static org.junit.Assert.assertEquals; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import org.eclipse.jgit.api.Git; | |
import org.eclipse.jgit.api.errors.GitAPIException; | |
import org.eclipse.jgit.lib.CommitBuilder; | |
import org.eclipse.jgit.lib.Constants; | |
import org.eclipse.jgit.lib.FileMode; | |
import org.eclipse.jgit.lib.ObjectId; | |
import org.eclipse.jgit.lib.ObjectInserter; | |
import org.eclipse.jgit.lib.ObjectLoader; | |
import org.eclipse.jgit.lib.ObjectReader; | |
import org.eclipse.jgit.lib.PersonIdent; | |
import org.eclipse.jgit.lib.Repository; | |
import org.eclipse.jgit.lib.TreeFormatter; | |
import org.eclipse.jgit.revwalk.RevCommit; | |
import org.eclipse.jgit.treewalk.TreeWalk; | |
import org.junit.After; | |
import org.junit.Before; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.rules.TemporaryFolder; | |
public class GitInternalsLearningTest { | |
@Rule | |
public final TemporaryFolder tempFolder = new TemporaryFolder(); | |
private Git git; | |
private Repository repository; | |
@Test | |
public void testCreateBlob() throws IOException { | |
String helloWorld = "Hello World!"; | |
ObjectId blobId = insertObject( Constants.OBJ_BLOB, helloWorld.getBytes( "utf-8" ) ); | |
ObjectLoader objectLoader = loadObject( blobId ); | |
assertEquals( Constants.OBJ_BLOB, objectLoader.getType() ); | |
assertEquals( helloWorld, new String( objectLoader.getBytes(), "utf-8" ) ); | |
} | |
@Test | |
public void testCreateTree() throws IOException { | |
ObjectId blobId = insertObject( Constants.OBJ_BLOB, "Hello World!".getBytes( "utf-8" ) ); | |
TreeFormatter treeFormatter = new TreeFormatter(); | |
treeFormatter.append( "hello-world.txt", FileMode.REGULAR_FILE, blobId ); | |
ObjectId treeId = insertObject( Constants.OBJ_TREE, treeFormatter.toByteArray() ); | |
assertEquals( Constants.OBJ_TREE, loadObject( treeId ).getType() ); | |
assertArrayEquals( new String[] { "hello-world.txt" }, listPathNames( treeId ) ); | |
} | |
@Test | |
public void testCreateCommit() throws IOException { | |
TreeFormatter treeFormatter = new TreeFormatter(); | |
ObjectId treeId = insertObject( Constants.OBJ_TREE, treeFormatter.toByteArray() ); | |
CommitBuilder commitBuilder = new CommitBuilder(); | |
commitBuilder.setTreeId( treeId ); | |
commitBuilder.setMessage( "My first commit!" ); | |
PersonIdent personIdent = new PersonIdent( "me", "me@example.com" ); | |
commitBuilder.setAuthor( personIdent ); | |
commitBuilder.setCommitter( personIdent ); | |
ObjectId commitId = insertObject( Constants.OBJ_COMMIT, commitBuilder.build() ); | |
RevCommit commit = RevCommit.parse( loadObject( commitId ).getBytes() ); | |
assertEquals( commitBuilder.getMessage(), commit.getFullMessage() ); | |
assertEquals( personIdent, commit.getAuthorIdent() ); | |
assertEquals( personIdent, commit.getCommitterIdent() ); | |
assertEquals( treeId, commit.getTree().getId() ); | |
assertEquals( 0, commit.getParentCount() ); | |
} | |
@Test | |
public void testCreateSubTree() throws IOException { | |
ObjectId blobId = insertObject( Constants.OBJ_BLOB, "content".getBytes( "utf-8" ) ); | |
TreeFormatter subTreeFormatter = new TreeFormatter(); | |
subTreeFormatter.append( "file.txt", FileMode.REGULAR_FILE, blobId ); | |
ObjectId subTreeId = insertObject( Constants.OBJ_TREE, subTreeFormatter.toByteArray() ); | |
TreeFormatter treeFormatter = new TreeFormatter(); | |
treeFormatter.append( "folder", FileMode.TREE, subTreeId ); | |
ObjectId treeId = insertObject( Constants.OBJ_TREE, treeFormatter.toByteArray() ); | |
assertArrayEquals( new String[] { "folder/file.txt", "folder" }, listPathNames( treeId ) ); | |
} | |
@Before | |
public void setUp() throws GitAPIException { | |
git = Git.init().setDirectory( tempFolder.getRoot() ).call(); | |
repository = git.getRepository(); | |
} | |
@After | |
public void tearDown() { | |
repository.close(); | |
} | |
private ObjectId insertObject( int type, byte[] content ) throws IOException { | |
ObjectInserter objectInserter = repository.newObjectInserter(); | |
ObjectId result = objectInserter.insert( type, content ); | |
objectInserter.flush(); | |
objectInserter.release(); | |
return result; | |
} | |
private ObjectLoader loadObject( ObjectId objectId ) throws IOException { | |
ObjectReader objectReader = repository.newObjectReader(); | |
ObjectLoader result = objectReader.open( objectId ); | |
objectReader.release(); | |
return result; | |
} | |
private String[] listPathNames( ObjectId treeId ) throws IOException { | |
Collection<String> pathNames = new ArrayList<>(); | |
TreeWalk treeWalk = new TreeWalk( repository ); | |
treeWalk.setRecursive( true ); | |
treeWalk.setPostOrderTraversal( true ); | |
treeWalk.addTree( treeId ); | |
while( treeWalk.next() ) { | |
pathNames.add( treeWalk.getPathString() ); | |
} | |
treeWalk.release(); | |
return ( String[] )pathNames.toArray( new String[ pathNames.size() ] ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment