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);
+ }
+}