Skip to content

Commit fb72382

Browse files
git-emsergiocabral
authored andcommitted
Update /book/B-embedding-git/sections/
1 parent 916a8fd commit fb72382

4 files changed

Lines changed: 152 additions & 29 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
=== Dulwich
2+
3+
(((Dulwich)))(((Python)))
4+
There is also a pure-Python Git implementation - Dulwich.
5+
The project is hosted under https://www.dulwich.io/
6+
It aims to provide an interface to git repositories (both local and remote) that doesn't call out to git directly but instead uses pure Python.
7+
It has an optional C extensions though, that significantly improve the performance.
8+
9+
Dulwich follows git design and separate two basic levels of API: plumbing and porcelain.
10+
11+
Here is an example of using the lower level API to access the commit message of the last commit:
12+
13+
[source, python]
14+
----
15+
from dulwich.repo import Repo
16+
r = Repo('.')
17+
r.head()
18+
# '57fbe010446356833a6ad1600059d80b1e731e15'
19+
20+
c = r[r.head()]
21+
c
22+
# <Commit 015fc1267258458901a94d228e39f0a378370466>
23+
24+
c.message
25+
# 'Add note about encoding.\n'
26+
----
27+
28+
To print a commit log using high-level porcelain API, one can use:
29+
30+
[source, python]
31+
----
32+
from dulwich import porcelain
33+
porcelain.log('.', max_entries=1)
34+
35+
#commit: 57fbe010446356833a6ad1600059d80b1e731e15
36+
#Author: Jelmer Vernooij <jelmer@jelmer.uk>
37+
#Date: Sat Apr 29 2017 23:57:34 +0000
38+
----
39+
40+
41+
==== Further Reading
42+
43+
* The official API documentation is available at https://www.dulwich.io/docs/api/[].
44+
* Official tutorial at https://www.dulwich.io/docs/tutorial[] has many examples of how to do specific tasks with Dulwich.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
=== go-git
2+
3+
(((go-git)))(((Go)))
4+
In case you want to integrate Git into a service written in Golang, there also is a pure Go library implementation.
5+
This implementation does not have any native dependencies and thus is not prone to manual memory management errors.
6+
It is also transparent for the standard Golang performance analysis tooling like CPU, Memory profilers, race detector, etc.
7+
8+
go-git is focused on extensibility, compatibility and supports most of the plumbing APIs, which is documented at https://github.com/go-git/go-git/blob/master/COMPATIBILITY.md[].
9+
10+
Here is a basic example of using Go APIs:
11+
12+
[source, go]
13+
----
14+
import "github.com/go-git/go-git/v5"
15+
16+
r, err := git.PlainClone("/tmp/foo", false, &git.CloneOptions{
17+
URL: "https://github.com/go-git/go-git",
18+
Progress: os.Stdout,
19+
})
20+
----
21+
22+
As soon as you have a `Repository` instance, you can access information and perform mutations on it:
23+
24+
[source, go]
25+
----
26+
// retrieves the branch pointed by HEAD
27+
ref, err := r.Head()
28+
29+
// get the commit object, pointed by ref
30+
commit, err := r.CommitObject(ref.Hash())
31+
32+
// retrieves the commit history
33+
history, err := commit.History()
34+
35+
// iterates over the commits and print each
36+
for _, c := range history {
37+
fmt.Println(c)
38+
}
39+
----
40+
41+
==== Advanced Functionality
42+
43+
go-git has few notable advanced features, one of which is a pluggable storage system, which is similar to Libgit2 backends.
44+
The default implementation is in-memory storage, which is very fast.
45+
46+
[source, go]
47+
----
48+
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
49+
URL: "https://github.com/go-git/go-git",
50+
})
51+
----
52+
53+
Pluggable storage provides many interesting options.
54+
For instance, https://github.com/go-git/go-git/tree/master/_examples/storage[] allows you to store references, objects, and configuration in an Aerospike database.
55+
56+
Another feature is a flexible filesystem abstraction.
57+
Using https://pkg.go.dev/github.com/go-git/go-billy/v5?tab=doc#Filesystem[] it is easy to store all the files in different way i.e by packing all of them to a single archive on disk or by keeping them all in-memory.
58+
59+
Another advanced use-case includes a fine-tunable HTTP client, such as the one found at https://github.com/go-git/go-git/blob/master/_examples/custom_http/main.go[].
60+
61+
[source, go]
62+
----
63+
customClient := &http.Client{
64+
Transport: &http.Transport{ // accept any certificate (might be useful for testing)
65+
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
66+
},
67+
Timeout: 15 * time.Second, // 15 second timeout
68+
CheckRedirect: func(req *http.Request, via []*http.Request) error {
69+
return http.ErrUseLastResponse // don't follow redirect
70+
},
71+
}
72+
73+
// Override http(s) default protocol to use our custom client
74+
client.InstallProtocol("https", githttp.NewClient(customClient))
75+
76+
// Clone repository using the new client if the protocol is https://
77+
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{URL: url})
78+
----
79+
80+
==== Further Reading
81+
82+
A full treatment of go-git's capabilities is outside the scope of this book.
83+
If you want more information on go-git, there's API documentation at https://pkg.go.dev/github.com/go-git/go-git/v5[], and a set of usage examples at https://github.com/go-git/go-git/tree/master/_examples[].

book/B-embedding-git/sections/jgit.asc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
=== JGit
22

3-
(((jgit)))(((java)))
3+
(((jgit)))(((Java)))
44
If you want to use Git from within a Java program, there is a fully featured Git library called JGit.
55
JGit is a relatively full-featured implementation of Git written natively in Java, and is widely used in the Java community.
6-
The JGit project is under the Eclipse umbrella, and its home can be found at http://www.eclipse.org/jgit[].
6+
The JGit project is under the Eclipse umbrella, and its home can be found at https://www.eclipse.org/jgit/[].
77

88
==== Getting Set Up
99

@@ -19,10 +19,10 @@ Probably the easiest is to use Maven – the integration is accomplished by addi
1919
</dependency>
2020
----
2121

22-
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.
22+
The `version` will most likely have advanced by the time you read this; check https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit[] for updated repository information.
2323
Once this step is done, Maven will automatically acquire and use the JGit libraries that you'll need.
2424

25-
If you would rather manage the binary dependencies yourself, pre-built JGit binaries are available from http://www.eclipse.org/jgit/download[].
25+
If you would rather manage the binary dependencies yourself, pre-built JGit binaries are available from https://www.eclipse.org/jgit/download[].
2626
You can build them into your project by running a command like this:
2727

2828
[source,console]
@@ -91,13 +91,13 @@ String name = cfg.getString("user", null, "name");
9191
There's quite a bit going on here, so let's go through it one section at a time.
9292

9393
The first line gets a pointer to the `master` reference.
94-
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.
94+
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.
9595
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()`).
96-
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.
96+
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.
9797

9898
The second line gets the target of the `master` reference, which is returned as an ObjectId instance.
9999
ObjectId represents the SHA-1 hash of an object, which might or might not exist in Git's object database.
100-
The third line is similar, but shows how JGit handles the rev-parse syntax (for more on this, see <<ch07-git-tools#r_branch_references>>); you can pass any object specifier that Git understands, and JGit will return either a valid ObjectId for that object, or `null`.
100+
The third line is similar, but shows how JGit handles the rev-parse syntax (for more on this, see <<ch07-git-tools#_branch_references>>); you can pass any object specifier that Git understands, and JGit will return either a valid ObjectId for that object, or `null`.
101101

102102
The next two lines show how to load the raw contents of an object.
103103
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.
@@ -128,7 +128,7 @@ Git git = new Git(repo);
128128
----
129129

130130
The Git class has a nice set of high-level _builder_-style methods that can be used to construct some pretty complex behavior.
131-
Let's take a look at an example doing something like `git ls-remote`:
131+
Let's take a look at an example -- doing something like `git ls-remote`:
132132

133133
[source,java]
134134
----

book/B-embedding-git/sections/libgit2.asc

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
(((libgit2)))((("C")))
44
Another option at your disposal is to use Libgit2.
55
Libgit2 is a dependency-free implementation of Git, with a focus on having a nice API for use within other programs.
6-
You can find it at http://libgit2.github.com[].
6+
You can find it at https://libgit2.org[].
77

88
First, let's take a look at what the C API looks like.
99
Here's a whirlwind tour:
1010

1111
[source,c]
12-
-----
12+
----
1313
// Open a repository
1414
git_repository *repo;
1515
int error = git_repository_open(&repo, "/path/to/repository");
@@ -28,16 +28,16 @@ const git_oid *tree_id = git_commit_tree_id(commit);
2828
// Cleanup
2929
git_commit_free(commit);
3030
git_repository_free(repo);
31-
-----
31+
----
3232

3333
The first couple of lines open a Git repository.
3434
The `git_repository` type represents a handle to a repository with a cache in memory.
3535
This is the simplest method, for when you know the exact path to a repository's working directory or `.git` folder.
3636
There's also the `git_repository_open_ext` which includes options for searching, `git_clone` and friends for making a local clone of a remote repository, and `git_repository_init` for creating an entirely new repository.
3737

38-
The second chunk of code uses rev-parse syntax (see <<ch07-git-tools#r_branch_references>> for more on this) to get the commit that HEAD eventually points to.
38+
The second chunk of code uses rev-parse syntax (see <<ch07-git-tools#_branch_references>> for more on this) to get the commit that HEAD eventually points to.
3939
The type returned is a `git_object` pointer, which represents something that exists in the Git object database for a repository.
40-
`git_object` is actually a ``parent'' type for several different kinds of objects; the memory layout for each of the ``child'' types is the same as for `git_object`, so you can safely cast to the right one.
40+
`git_object` is actually a "`parent`" type for several different kinds of objects; the memory layout for each of the "`child`" types is the same as for `git_object`, so you can safely cast to the right one.
4141
In this case, `git_object_type(commit)` would return `GIT_OBJ_COMMIT`, so it's safe to cast to a `git_commit` pointer.
4242

4343
The next chunk shows how to access the commit's properties.
@@ -66,7 +66,7 @@ tree = commit.tree
6666
----
6767

6868
As you can see, the code is much less cluttered.
69-
Firstly, Rugged uses exceptions; it can raise things like `ConfigError` or `ObjectError` to signal error conditions.
69+
Firstly, Rugged uses exceptions; it can raise things like `ConfigError` or `ObjectError` to signal error conditions.
7070
Secondly, there's no explicit freeing of resources, since Ruby is garbage-collected.
7171
Let's take a look at a slightly more complicated example: crafting a commit from scratch
7272

@@ -106,13 +106,12 @@ commit = repo.lookup(commit_id) # <8>
106106
<8> The return value is the SHA-1 hash of a new commit object, which you can then use to get a `Commit` object.
107107

108108
The Ruby code is nice and clean, but since Libgit2 is doing the heavy lifting, this code will run pretty fast, too.
109-
If you're not a rubyist, we touch on some other bindings in <<r_libgit2_bindings>>.
110-
109+
If you're not a rubyist, we touch on some other bindings in <<_libgit2_bindings>>.
111110

112111
==== Advanced Functionality
113112

114113
Libgit2 has a couple of capabilities that are outside the scope of core Git.
115-
One example is pluggability: Libgit2 allows you to provide custom ``backends'' for several types of operation, so you can store things in a different way than stock Git does.
114+
One example is pluggability: Libgit2 allows you to provide custom "`backends`" for several types of operation, so you can store things in a different way than stock Git does.
116115
Libgit2 allows custom backends for configuration, ref storage, and the object database, among other things.
117116

118117
Let's take a look at how this works.
@@ -131,12 +130,12 @@ error = git_odb_add_backend(odb, my_backend, 1); // <3>
131130
132131
git_repository *repo;
133132
error = git_repository_open(&repo, "some-path");
134-
error = git_repository_set_odb(odb); // <4>
133+
error = git_repository_set_odb(repo, odb); // <4>
135134
----
136135

137-
_(Note that errors are captured, but not handled. We hope your code is better than ours.)_
136+
_Note that errors are captured, but not handled. We hope your code is better than ours._
138137

139-
<1> Initialize an empty object database (ODB) ``frontend,'' which will act as a container for the ``backends'' which are the ones doing the real work.
138+
<1> Initialize an empty object database (ODB) "`frontend,`" which will act as a container for the "`backends`" which are the ones doing the real work.
140139
<2> Initialize a custom ODB backend.
141140
<3> Add the backend to the frontend.
142141
<4> Open a repository, and set it to use our ODB to look up objects.
@@ -179,15 +178,14 @@ The rest of it is arbitrary; this structure can be as large or small as you need
179178
The initialization function allocates some memory for the structure, sets up the custom context, and then fills in the members of the `parent` structure that it supports.
180179
Take a look at the `include/git2/sys/odb_backend.h` file in the Libgit2 source for a complete set of call signatures; your particular use case will help determine which of these you'll want to support.
181180

182-
[[r_libgit2_bindings]]
181+
[[_libgit2_bindings]]
183182
==== Other Bindings
184183

185184
Libgit2 has bindings for many languages.
186185
Here we show a small example using a few of the more complete bindings packages as of this writing; libraries exist for many other languages, including C++, Go, Node.js, Erlang, and the JVM, all in various stages of maturity.
187186
The official collection of bindings can be found by browsing the repositories at https://github.com/libgit2[].
188187
The code we'll write will return the commit message from the commit eventually pointed to by HEAD (sort of like `git log -1`).
189188

190-
191189
===== LibGit2Sharp
192190

193191
(((.NET)))(((C#)))(((Mono)))
@@ -196,9 +194,9 @@ The bindings are written in C#, and great care has been taken to wrap the raw Li
196194
Here's what our example program looks like:
197195

198196
[source,csharp]
199-
-----
197+
----
200198
new Repository(@"C:\path\to\repo").Head.Tip.Message;
201-
-----
199+
----
202200

203201
For desktop Windows applications, there's even a NuGet package that will help you get started quickly.
204202

@@ -210,19 +208,18 @@ Objective-Git (https://github.com/libgit2/objective-git[]) is the name of the Li
210208
The example program looks like this:
211209

212210
[source,objc]
213-
-----
211+
----
214212
GTRepository *repo =
215213
[[GTRepository alloc] initWithURL:[NSURL fileURLWithPath: @"/path/to/repo"] error:NULL];
216214
NSString *msg = [[[repo headReferenceWithError:NULL] resolvedTarget] message];
217-
-----
215+
----
218216

219217
Objective-git is fully interoperable with Swift, so don't fear if you've left Objective-C behind.
220218

221-
222219
===== pygit2
223220

224221
(((Python)))
225-
The bindings for Libgit2 in Python are called Pygit2, and can be found at http://www.pygit2.org/[].
222+
The bindings for Libgit2 in Python are called Pygit2, and can be found at https://www.pygit2.org[].
226223
Our example program:
227224

228225
[source,python]
@@ -233,7 +230,6 @@ pygit2.Repository("/path/to/repo") # open repository
233230
.message # read the message
234231
----
235232

236-
237233
==== Further Reading
238234

239235
Of course, a full treatment of Libgit2's capabilities is outside the scope of this book.

0 commit comments

Comments
 (0)