diff --git a/jgit/README.md b/jgit/README.md new file mode 100644 index 0000000000..5c65f1101b --- /dev/null +++ b/jgit/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [A Guide to JGit](http://www.baeldung.com/jgit) diff --git a/jgit/pom.xml b/jgit/pom.xml new file mode 100644 index 0000000000..deae1e45e3 --- /dev/null +++ b/jgit/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + com.baeldung + JGit + 1.0-SNAPSHOT + JGit + jar + http://maven.apache.org + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + jgit-repository + https://repo.eclipse.org/content/groups/releases/ + + + + + + + org.eclipse.jgit + org.eclipse.jgit + ${org.eclipse.jgit.version} + + + org.eclipse.jgit + org.eclipse.jgit.archive + ${org.eclipse.jgit.version} + + + commons-io + commons-io + ${commons-io.version} + + + org.slf4j + slf4j-simple + ${org.slf4j.version} + + + + + 4.5.0.201609210915-r + + + \ No newline at end of file diff --git a/jgit/src/main/java/com/baeldung/jgit/CreateNewRepository.java b/jgit/src/main/java/com/baeldung/jgit/CreateNewRepository.java new file mode 100644 index 0000000000..1702efc315 --- /dev/null +++ b/jgit/src/main/java/com/baeldung/jgit/CreateNewRepository.java @@ -0,0 +1,30 @@ +package com.baeldung.jgit; + +import java.io.File; +import java.io.IOException; +import org.apache.commons.io.FileUtils; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; + +/** + * Simple snippet which shows how to create a new repository + * + * + */ +public class CreateNewRepository { + + public static void main(String[] args) throws IOException, IllegalStateException, GitAPIException { + // prepare a new folder + File localPath = File.createTempFile("TestGitRepository", ""); + if(!localPath.delete()) { + throw new IOException("Could not delete temporary file " + localPath); + } + + // create the directory + try (Git git = Git.init().setDirectory(localPath).call()) { + System.out.println("Having repository: " + git.getRepository().getDirectory()); + } + + FileUtils.deleteDirectory(localPath); + } +} diff --git a/jgit/src/main/java/com/baeldung/jgit/OpenRepository.java b/jgit/src/main/java/com/baeldung/jgit/OpenRepository.java new file mode 100644 index 0000000000..671df2a844 --- /dev/null +++ b/jgit/src/main/java/com/baeldung/jgit/OpenRepository.java @@ -0,0 +1,65 @@ +package com.baeldung.jgit; + +import com.baeldung.jgit.helper.Helper; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import java.io.File; +import java.io.IOException; + +/** + * Simple snippet which shows how to open an existing repository + * + * + */ +public class OpenRepository { + + public static void main(String[] args) throws IOException, GitAPIException { + // first create a test-repository, the return is including the .get directory here! + File repoDir = createSampleGitRepo(); + + // now open the resulting repository with a FileRepositoryBuilder + FileRepositoryBuilder builder = new FileRepositoryBuilder(); + try (Repository repository = builder.setGitDir(repoDir) + .readEnvironment() // scan environment GIT_* variables + .findGitDir() // scan up the file system tree + .build()) { + System.out.println("Having repository: " + repository.getDirectory()); + + // the Ref holds an ObjectId for any type of object (tree, commit, blob, tree) + Ref head = repository.exactRef("refs/heads/master"); + System.out.println("Ref of refs/heads/master: " + head); + } + } + + private static File createSampleGitRepo() throws IOException, GitAPIException { + try (Repository repository = Helper.createNewRepository()) { + System.out.println("Temporary repository at " + repository.getDirectory()); + + // create the file + File myfile = new File(repository.getDirectory().getParent(), "testfile"); + if(!myfile.createNewFile()) { + throw new IOException("Could not create file " + myfile); + } + + // run the add-call + try (Git git = new Git(repository)) { + git.add() + .addFilepattern("testfile") + .call(); + + + // and then commit the changes + git.commit() + .setMessage("Added testfile") + .call(); + } + + System.out.println("Added file " + myfile + " to repository at " + repository.getDirectory()); + + return repository.getDirectory(); + } + } +} diff --git a/jgit/src/main/java/com/baeldung/jgit/helper/Helper.java b/jgit/src/main/java/com/baeldung/jgit/helper/Helper.java new file mode 100644 index 0000000000..39d7b767d2 --- /dev/null +++ b/jgit/src/main/java/com/baeldung/jgit/helper/Helper.java @@ -0,0 +1,33 @@ + +package com.baeldung.jgit.helper; + +import java.io.File; +import java.io.IOException; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; + +public class Helper { + + public static Repository openJGitRepository() throws IOException { + FileRepositoryBuilder builder = new FileRepositoryBuilder(); + return builder + .readEnvironment() // scan environment GIT_* variables + .findGitDir() // scan up the file system tree + .build(); + } + + public static Repository createNewRepository() throws IOException { + // prepare a new folder + File localPath = File.createTempFile("TestGitRepository", ""); + if(!localPath.delete()) { + throw new IOException("Could not delete temporary file " + localPath); + } + + // create the directory + Repository repository = FileRepositoryBuilder.create(new File(localPath, ".git")); + repository.create(); + + return repository; + } + +} diff --git a/jgit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java new file mode 100644 index 0000000000..314366f08c --- /dev/null +++ b/jgit/src/main/java/com/baeldung/jgit/porcelain/AddFile.java @@ -0,0 +1,36 @@ +package com.baeldung.jgit.porcelain; + +import java.io.File; +import java.io.IOException; +import com.baeldung.jgit.helper.Helper; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Repository; + +/** + * Simple snippet which shows how to add a file to the index + * + * + */ +public class AddFile { + + public static void main(String[] args) throws IOException, GitAPIException { + // prepare a new test-repository + try (Repository repository = Helper.createNewRepository()) { + try (Git git = new Git(repository)) { + // create the file + File myfile = new File(repository.getDirectory().getParent(), "testfile"); + if(!myfile.createNewFile()) { + throw new IOException("Could not create file " + myfile); + } + + // run the add-call + git.add() + .addFilepattern("testfile") + .call(); + + System.out.println("Added file " + myfile + " to repository at " + repository.getDirectory()); + } + } + } +} diff --git a/jgit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java new file mode 100644 index 0000000000..4c0956ebf8 --- /dev/null +++ b/jgit/src/main/java/com/baeldung/jgit/porcelain/CommitAll.java @@ -0,0 +1,51 @@ +package com.baeldung.jgit.porcelain; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import com.baeldung.jgit.helper.Helper; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Repository; + +/** + * Simple snippet which shows how to commit all files + * + * + */ +public class CommitAll { + + public static void main(String[] args) throws IOException, GitAPIException { + // prepare a new test-repository + try (Repository repository = Helper.createNewRepository()) { + try (Git git = new Git(repository)) { + // create the file + File myfile = new File(repository.getDirectory().getParent(), "testfile"); + if(!myfile.createNewFile()) { + throw new IOException("Could not create file " + myfile); + } + + // Stage all files in the repo including new files + git.add().addFilepattern(".").call(); + + // and then commit the changes. + git.commit() + .setMessage("Commit all changes including additions") + .call(); + + try(PrintWriter writer = new PrintWriter(myfile)) { + writer.append("Hello, world!"); + } + + // Stage all changed files, omitting new files, and commit with one command + git.commit() + .setAll(true) + .setMessage("Commit changes to all files") + .call(); + + + System.out.println("Committed all changes to repository at " + repository.getDirectory()); + } + } + } +} diff --git a/jgit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java new file mode 100644 index 0000000000..0f735daf8c --- /dev/null +++ b/jgit/src/main/java/com/baeldung/jgit/porcelain/CreateAndDeleteTag.java @@ -0,0 +1,56 @@ +package com.baeldung.jgit.porcelain; + +import java.io.IOException; +import com.baeldung.jgit.helper.Helper; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; + +/** + * Simple snippet which shows how to create a tag + * + * + */ +public class CreateAndDeleteTag { + + public static void main(String[] args) throws IOException, GitAPIException { + // prepare test-repository + try (Repository repository = Helper.openJGitRepository()) { + try (Git git = new Git(repository)) { + // remove the tag before creating it + git.tagDelete().setTags("tag_for_testing").call(); + + // set it on the current HEAD + Ref tag = git.tag().setName("tag_for_testing").call(); + System.out.println("Created/moved tag " + tag + " to repository at " + repository.getDirectory()); + + // remove the tag again + git.tagDelete().setTags("tag_for_testing").call(); + + // read some other commit and set the tag on it + ObjectId id = repository.resolve("HEAD^"); + try (RevWalk walk = new RevWalk(repository)) { + RevCommit commit = walk.parseCommit(id); + tag = git.tag().setObjectId(commit).setName("tag_for_testing").call(); + System.out.println("Created/moved tag " + tag + " to repository at " + repository.getDirectory()); + + // remove the tag again + git.tagDelete().setTags("tag_for_testing").call(); + + // create an annotated tag + tag = git.tag().setName("tag_for_testing").setAnnotated(true).call(); + System.out.println("Created/moved tag " + tag + " to repository at " + repository.getDirectory()); + + // remove the tag again + git.tagDelete().setTags("tag_for_testing").call(); + + walk.dispose(); + } + } + } + } +} diff --git a/jgit/src/main/java/com/baeldung/jgit/porcelain/Log.java b/jgit/src/main/java/com/baeldung/jgit/porcelain/Log.java new file mode 100644 index 0000000000..a50028a9ae --- /dev/null +++ b/jgit/src/main/java/com/baeldung/jgit/porcelain/Log.java @@ -0,0 +1,74 @@ +package com.baeldung.jgit.porcelain; + +import java.io.IOException; +import com.baeldung.jgit.helper.Helper; +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; + +/** + * Simple snippet which shows how to get the commit-ids for a file to provide log information. + * + * + */ +public class Log { + + @SuppressWarnings("unused") + public static void main(String[] args) throws IOException, GitAPIException { + try (Repository repository = Helper.openJGitRepository()) { + try (Git git = new Git(repository)) { + Iterable logs = git.log() + .call(); + int count = 0; + for (RevCommit rev : logs) { + //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */); + count++; + } + System.out.println("Had " + count + " commits overall on current branch"); + + logs = git.log() + .add(repository.resolve(git.getRepository().getFullBranch())) + .call(); + count = 0; + for (RevCommit rev : logs) { + System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */); + count++; + } + System.out.println("Had " + count + " commits overall on "+git.getRepository().getFullBranch()); + + logs = git.log() + .all() + .call(); + count = 0; + for (RevCommit rev : logs) { + //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */); + count++; + } + System.out.println("Had " + count + " commits overall in repository"); + + logs = git.log() + // for all log.all() + .addPath("README.md") + .call(); + count = 0; + for (RevCommit rev : logs) { + //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */); + count++; + } + System.out.println("Had " + count + " commits on README.md"); + + logs = git.log() + // for all log.all() + .addPath("pom.xml") + .call(); + count = 0; + for (RevCommit rev : logs) { + //System.out.println("Commit: " + rev /* + ", name: " + rev.getName() + ", id: " + rev.getId().getName() */); + count++; + } + System.out.println("Had " + count + " commits on pom.xml"); + } + } + } +} diff --git a/jgit/src/main/resources/logback.xml b/jgit/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/jgit/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/jgit/src/test/java/com/baeldung/jgit/JGitBugIntegrationTest.java b/jgit/src/test/java/com/baeldung/jgit/JGitBugIntegrationTest.java new file mode 100644 index 0000000000..ad34890996 --- /dev/null +++ b/jgit/src/test/java/com/baeldung/jgit/JGitBugIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.jgit; + +import com.baeldung.jgit.helper.Helper; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ObjectReader; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevWalk; +import org.junit.Test; +import java.io.IOException; +import static org.junit.Assert.assertNotNull; + +/** + * Tests which show issues with JGit that we reported upstream. + */ +public class JGitBugIntegrationTest { + @Test + public void testRevWalkDisposeClosesReader() throws IOException { + try (Repository repo = Helper.openJGitRepository()) { + try (ObjectReader reader = repo.newObjectReader()) { + try (RevWalk walk = new RevWalk(reader)) { + walk.dispose(); + + Ref head = repo.exactRef("refs/heads/master"); + System.out.println("Found head: " + head); + + ObjectLoader loader = reader.open(head.getObjectId()); + assertNotNull(loader); + } + } + } + } +} diff --git a/jgit/src/test/java/com/baeldung/jgit/porcelain/PorcelainUnitTest.java b/jgit/src/test/java/com/baeldung/jgit/porcelain/PorcelainUnitTest.java new file mode 100644 index 0000000000..d3b3358664 --- /dev/null +++ b/jgit/src/test/java/com/baeldung/jgit/porcelain/PorcelainUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.jgit.porcelain; + +import org.junit.Test; + +public class PorcelainUnitTest { + @Test + public void runSamples() throws Exception { + // simply call all the samples to see any severe problems with the samples + AddFile.main(null); + + CommitAll.main(null); + + CreateAndDeleteTag.main(null); + + Log.main(null); + } +}