Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translate B-embedding-git jgit #125

Merged
merged 7 commits into from
Aug 14, 2015
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 65 additions & 65 deletions book/B-embedding-git/sections/jgit.asc
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
=== JGit

(((jgit)))(((java)))
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[].
如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库,那就是 JGit
JGit 是一个相对来说功能比较全的用 Java 写成的 Git 的实现,并且它在 Java 社区中被广泛使用。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JGit 是一个用 Java 写成的功能相对建全的 Git 的实现,它在 Java 社区中被广泛使用。

JGit 工程由 Eclipse 维护,它的主页在 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:
有很多种方式可以让 JGit 去连接你的工程,并依靠它去写代码。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有很多种方式可以让 JGit 连接你的工程,并依靠它去写代码。
去掉感觉更通顺些

最简单的方式也许就是使用 Maven 。你可以通过在你的 pom.xml 文件里的 `dependencies` 标签中增加像下面这样的片段来完成这个整合。

[source,xml]
----
Expand All @@ -19,115 +19,115 @@ Probably the easiest is to use Maven – the integration is accomplished by addi
</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.
`version` 很有可能在你读到这段文字的时候已经更新了,所以请浏览 http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit[] 以获取最新的仓库信息。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在你读到这段文字时 version 很可能已经更新了

当这一步完成之后, Maven 就会自动获取并使用你所需要的 JGit 库。

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:
如果你想自己管理二进制的依赖包,那么你可以从 http://www.eclipse.org/jgit/download[] 获得预构建的 JGit 二进制文件。
你可以像下面这样执行一个命令来将它们构建进你的工程。

[source,shell]
----
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.
JGit API 有两种基本的层次:底层命令和高层命令。
这个两个术语都来自 Git ,并且 JGit 也被粗略地按照相同的方式划分:高层 API 是一个面向普通用户级别功能的友好的前端(一系列普通用户使用 Git 命令行工具时可能用到的东西),底层 API 则直接作用于低级的仓库对象。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

并且 JGit 也被按照相同的方式粗略地划分


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`:
对于大多数 JGit 会话,一般都以 `Repository` 类作为起点。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

大多数 JGit 会话会以 Repository 类作为起点,你首先要做的事就是创建一个它的实例。

对于一个基于文件系统的仓库来说(嗯, JGit 允许其它的存储模型),用 `FileRepositoryBuilder` 完成它。

[source,java]
----
// 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.
这个 builder 拥有提供所有让它找到一个 Git 仓库所需的方法的 API ,不管你的程序是否知道这个仓库的确切位置。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

无论你的程序是否知道仓库的确切位置,builder 中的那个 fluent API 都可以提供给它寻找仓库所需所有信息。
fluent API 感觉还是不翻译的好,度娘了一下没找到恰当的翻译

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IceNature 感觉 fluent 在这里只是修饰 API 这个名词的一个形容词。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Geno1024 但是要如何翻译呢?流畅的 API?没法表达原本的意思啊

它可以使用环境变量 (`.readEnvironment()`) ,从工作目录的某处来开始并搜索 (`.setWorkTree(…).findGitDir()`) , 或者仅仅只是像上面那样打开一个已知的 `.git` 目录。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

从工作目录的某处开始并搜索


Once you have a `Repository` instance, you can do all sorts of things with it.
Here's a quick sampling:
当你拥有一个 `Repository` 实例后,你就能对它做各种各样的事。
下面是一个速览:

[source,java]
----
// 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.
这里完成了一大堆事情,所以我们还是一次看清楚一段的好。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一次理解一段的好


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.
第一行获取一个指向 `master` 引用的指针。
JGit 自动抓取位于 `refs/heads/master` 的 _真正的_ master 引用,并返回一个允许你获取该引用的信息的对象。
你可以获取它的名字 (`.getName()`) ,或者一个直接引用的目标对象 (`.getObjectId()`) ,或者一个指向该引用的符号指针 (`.getTarget()`) 。
引用对象也经常被用来表示标签的引用和对象,所以你可以询问某个标签是否被 ``削除'' 了,或者说它指向一个标签对象的(也许很长的)字符串的最终目标。

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`.
第二行获得以 `master` 引用的目标,它返回一个 ObjectId 实例。
ObjectId 代表了一个对象的 SHA-1 哈希,不管它是否存在于一个 Git 对象的数据库。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不管它是否存在于一个 Git 对象的数据库,ObjectId 都会代表一个对象的 SHA-1 哈希。

第三行与此相似,但是它展示了 JGit 如何处理 rev-parse 语法(要了解更多,请看 <<_branch_references>> ),你可以传入任何 Git 了解的对象说明符,然后 JGit 会返回该对象的一个有效的 ObjectId ,或者 `null` 。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

从这里开始 diff 错位了。。。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个错位是由 Git 工具的检测的 Bug 造成的。

接下来两行展示了如何装载一个对象的原始内容。
在这个例子中,我们调用 `ObjectLoader.copyTo()` 让对象的内容直接流向标准输出流,但是 ObjectLoader 还带有读取对象的类型和长度并将它以字节数组返回的方法。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我们调用 ObjectLoader.copyTo() 直接向标准输出流输出对象的内容,除此之外 ObjectLoader 还带有……

对于一个( `.isLarge()` 返回 `true` 的)大的对象,你可以调用 `.openStream()` 来获得一个类似 InputStream 的对象,它可以在没有一次性将所有数据拉到内存的前提下读取对象的原始数据。

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.
接下来几行展现了让它创建一个新分支的方法。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

接下来几行展现了如何创建一个新的分支。

我们创建一个 RefUpdate 实例,配置一些参数,然后调用 `.update()` 来确认这个更改。
删除相同分支的代码就在这行下面。
记住必须先 `.setForceUpdate(true)` 才能让它工作,否则调用 `.delete()` 只会返回 `REJECTED` ,然后什么都没有发生。

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.
最后一个例子展示了如何从 Git 配置文件中获取 `user.name` 的值。
这个 Config 实例使用我们先前打开的仓库做本地配置,但是它也会自动地检测并读取全局和系统的配置文件。

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.
这只是底层 API 的冰山一角,另外还有许多可以使用的方法和类。
还有一个没有放在这里说明的就是 JGit 用异常来处理错误的方法。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还有一个没有放在这里说明的,就是 JGit 是用异常机制来处理错误的。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get√

JGit API 有时使用标准的 Java 异常(例如 `IOException` ),但是它也提供了大量 JGit 自己定义的异常类型(例如 `NoRemoteRepositoryException`, `CorruptObjectException`,和 `NoMergeBaseException`)。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

例如 NoRemoteRepositoryExceptionCorruptObjectException,和 NoMergeBaseException
=>
例如 NoRemoteRepositoryExceptionCorruptObjectExceptionNoMergeBaseException


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:
底层 API 更加完善,但是有时将它们串起来以实现普通的目的非常困难,例如将一个文件添加到索引,或者创建一个新的提交。
为了解决这个问题, JGit 提供了一系列高层 API 并且使用这些 API 的入口点就是 `Git` 类:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为了解决这个问题, JGit 提供了一系列高层 API ,使用这些 API 的入口点就是 Git 类:


[source,java]
----
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`:
Git 类有一系列非常好的_构建器_风格的高层方法,它可以用来构造一些复杂的行为。
我们来看一个例子——做一件类似 `git ls-remote` 的事。

[source,java]
----
Expand All @@ -143,18 +143,18 @@ for (Ref ref : remoteRefs) {
}
----

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.
这是一个 Git 类的公共样式,这个方法返回一个可以让你串连若干方法调用来设置参数的命令对象,当你调用 `.call()` 时它们就会被执行。
在这情况下,我们只是请求了 `origin` 远程的标签,而不是头部。
还要注意用于验证的 `CredentialsProvider` 对象的使用。

Many other commands are available through the Git class, including but not limited to `add`, `blame`, `commit`, `clean`, `push`, `rebase`, `revert`, and `reset`.
Git 类中还可以使用其它的许多命令,包括但不限于 `add``blame``commit``clean``push``rebase``revert`,和`reset`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在 Git 类中还可以使用许多其他的命令


==== 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:
这只是 JGit 的全部能力的冰山一角。
如果你对这有兴趣并且想深入学习,在下面可以找到一些信息和灵感。

* The official JGit API documentation is available online at http://download.eclipse.org/jgit/docs/latest/apidocs[].
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.
* There are several good resources pointed out at http://stackoverflow.com/questions/6861881[].
* JGit API 在线官方文档: http://download.eclipse.org/jgit/docs/latest/apidocs[]
这是基本的 Javadoc ,所以你也可以在你最喜欢的 JVM IDE 上安装它们到本地。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JVM IDE 上将它们安装到本地

* JGit Cookbook https://github.com/centic9/jgit-cookbook[] 拥有许多如何利用 JGit 实现特定任务的例子。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如何利用 JGit 实现
(JGit前多了一个空格)

* http://stackoverflow.com/questions/6861881[] 指出了几个好的资源。
2 changes: 1 addition & 1 deletion status.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
"B-embedding-git": {
"1-embedding-git.asc": 100,
"sections/command-line.asc": 100,
"sections/jgit.asc": 0,
"sections/jgit.asc": 100,
"sections/libgit2.asc": 0
},
"C-git-commands": {
Expand Down