-
1. Per Iniziare
- 1.1 Il Controllo di Versione
- 1.2 Una Breve Storia di Git
- 1.3 Cos’é Git?
- 1.4 La riga di comando
- 1.5 Installing Git
- 1.6 First-Time Git Setup
- 1.7 Chiedere aiuto
- 1.8 Sommario
-
2. Git Basics
- 2.1 Getting a Git Repository
- 2.2 Recording Changes to the Repository
- 2.3 Viewing the Commit History
- 2.4 Undoing Things
- 2.5 Working with Remotes
- 2.6 Tagging
- 2.7 Git Aliases
- 2.8 Sommario
-
3. Git Branching
- 3.1 Branches in a Nutshell
- 3.2 Basic Branching and Merging
- 3.3 Branch Management
- 3.4 Branching Workflows
- 3.5 Remote Branches
- 3.6 Rebasing
- 3.7 Summary
-
4. Git on the Server
- 4.1 The Protocols
- 4.2 Getting Git on a Server
- 4.3 Generating Your SSH Public Key
- 4.4 Setting Up the Server
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Third Party Hosted Options
- 4.10 Summary
-
5. Distributed Git
- 5.1 Distributed Workflows
- 5.2 Contributing to a Project
- 5.3 Maintaining a Project
- 5.4 Summary
-
6. GitHub
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Summary
-
8. Customizing Git
- 8.1 Git Configuration
- 8.2 Git Attributes
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Summary
-
9. Git and Other Systems
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Summary
-
10. Git Internals
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Summary
-
A1. Appendice A: Git in altri contesti
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in Powershell
- A1.7 Riassunto
-
A2. Appendice B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendice C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
A2.3 Appendice B: Embedding Git in your Applications - JGit
JGit
If you want to use Git from within a Java program, there is a fully featured Git library called JGit. JGit is a relatively full-featured implementation of Git written natively in Java, and is widely used in the Java community. The JGit project is under the Eclipse umbrella, and its home can be found at http://www.eclipse.org/jgit.
Getting Set Up
There are a number of ways to connect your project with JGit and start writing code against it.
Probably the easiest is to use Maven – the integration is accomplished by adding the following snipped to the <dependencies>
tag in your pom.xml file:
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>3.5.0.201409260305-r</version>
</dependency>
The version
will most likely have advanced by the time you read this; check http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit for updated repository information.
Once this step is done, Maven will automatically acquire and use the JGit libraries that you’ll need.
If you would rather manage the binary dependencies yourself, pre-built JGit binaries are available from http://www.eclipse.org/jgit/download. You can build them into your project by running a command like this:
javac -cp .:org.eclipse.jgit-3.5.0.201409260305-r.jar App.java
java -cp .:org.eclipse.jgit-3.5.0.201409260305-r.jar App
Plumbing
JGit has two basic levels of API: plumbing and porcelain. The terminology for these comes from Git itself, and JGit is divided into roughly the same kinds of areas: porcelain APIs are a friendly front-end for common user-level actions (the sorts of things a normal user would use the Git command-line tool for), while the plumbing APIs are for interacting with low-level repository objects directly.
The starting point for most JGit sessions is the Repository
class, and the first thing you’ll want to do is create an instance of it.
For a filesystem-based repository (yes, JGit allows for other storage models), this is accomplished using FileRepositoryBuilder
:
// Create a new repository; the path must exist
Repository newlyCreatedRepo = FileRepositoryBuilder.create(
new File("/tmp/new_repo/.git"));
// Open an existing repository
Repository existingRepo = new FileRepositoryBuilder()
.setGitDir(new File("my_repo/.git"))
.build();
The builder has a fluent API for providing all the things it needs to find a Git repository, whether or not your program knows exactly where it’s located.
It can use environment variables (.readEnvironment()
), start from a place in the working directory and search (.setWorkTree(…).findGitDir()
), or just open a known .git
directory as above.
Once you have a Repository
instance, you can do all sorts of things with it.
Here’s a quick sampling:
// Get a reference
Ref master = repo.getRef("master");
// Get the object the reference points to
ObjectId masterTip = master.getObjectId();
// Rev-parse
ObjectId obj = repo.resolve("HEAD^{tree}");
// Load raw object contents
ObjectLoader loader = r.open(masterTip);
loader.copyTo(System.out);
// Create a branch
RefUpdate createBranch1 = r.updateRef("refs/heads/branch1");
createBranch1.setNewObjectId(masterTip);
createBranch1.update();
// Delete a branch
RefUpdate deleteBranch1 = r.updateRef("refs/heads/branch1");
deleteBranch1.setForceUpdate(true);
deleteBranch1.delete();
// Config
Config cfg = r.getConfig();
String name = cfg.getString("user", null, "name");
There’s quite a bit going on here, so let’s go through it one section at a time.
The first line gets a pointer to the master
reference.
JGit automatically grabs the actual master ref, which lives at refs/heads/master
, and returns an object that lets you fetch information about the reference.
You can get the name (.getName()
), and either the target object of a direct reference (.getObjectId()
) or the reference pointed to by a symbolic ref (.getTarget()
).
Ref objects are also used to represent tag refs and objects, so you can ask if the tag is “peeled,” meaning that it points to the final target of a (potentially long) string of tag objects.
The second line gets the target of the master
reference, which is returned as an ObjectId instance.
ObjectId represents the SHA-1 hash of an object, which might or might not exist in Git’s object database.
The third line is similar, but shows how JGit handles the rev-parse syntax (for more on this, see Branch References); you can pass any object specifier that Git understands, and JGit will return either a valid ObjectId for that object, or null
.
The next two lines show how to load the raw contents of an object.
In this example, we call ObjectLoader.copyTo()
to stream the contents of the object directly to stdout, but ObjectLoader also has methods to read the type and size of an object, as well as return it as a byte array.
For large objects (where .isLarge()
returns true
), you can call .openStream()
to get an InputStream-like object that can read the raw object data without pulling it all into memory at once.
The next few lines show what it takes to create a new branch.
We create a RefUpdate instance, configure some parameters, and call .update()
to trigger the change.
Directly following this is the code to delete that same branch.
Note that .setForceUpdate(true)
is required for this to work; otherwise the .delete()
call will return REJECTED
, and nothing will happen.
The last example shows how to fetch the user.name
value from the Git configuration files.
This Config instance uses the repository we opened earlier for local configuration, but will automatically detect the global and system configuration files and read values from them as well.
This is only a small sampling of the full plumbing API; there are many more methods and classes available.
Also not shown here is the way JGit handles errors, which is through the use of exceptions.
JGit APIs sometimes throw standard Java exceptions (such as IOException
), but there are a host of JGit-specific exception types that are provided as well (such as NoRemoteRepositoryException
, CorruptObjectException
, and NoMergeBaseException
).
Porcelain
The plumbing APIs are rather complete, but it can be cumbersome to string them together to achieve common goals, like adding a file to the index, or making a new commit.
JGit provides a higher-level set of APIs to help out with this, and the entry point to these APIs is the Git
class:
Repository repo;
// construct repo...
Git git = new Git(repo);
The Git class has a nice set of high-level builder-style methods that can be used to construct some pretty complex behavior.
Let’s take a look at an example – doing something like git ls-remote
:
CredentialsProvider cp = new UsernamePasswordCredentialsProvider("username", "p4ssw0rd");
Collection<Ref> remoteRefs = git.lsRemote()
.setCredentialsProvider(cp)
.setRemote("origin")
.setTags(true)
.setHeads(false)
.call();
for (Ref ref : remoteRefs) {
System.out.println(ref.getName() + " -> " + ref.getObjectId().name());
}
This is a common pattern with the Git class; the methods return a command object that lets you chain method calls to set parameters, which are executed when you call .call()
.
In this case, we’re asking the origin
remote for tags, but not heads.
Also notice the use of a CredentialsProvider
object for authentication.
Many other commands are available through the Git class, including but not limited to add
, blame
, commit
, clean
, push
, rebase
, revert
, and reset
.
Further Reading
This is only a small sampling of JGit’s full capabilities. If you’re interested and want to learn more, here’s where to look for information and inspiration:
-
The official JGit API documentation is available online at https://www.eclipse.org/jgit/documentation. These are standard Javadoc, so your favorite JVM IDE will be able to install them locally, as well.
-
The JGit Cookbook at https://github.com/centic9/jgit-cookbook has many examples of how to do specific tasks with JGit.