diff --git a/book/10-git-internals/sections/objects.asc b/book/10-git-internals/sections/objects.asc index c34f8439..c7aaef24 100644 --- a/book/10-git-internals/sections/objects.asc +++ b/book/10-git-internals/sections/objects.asc @@ -13,7 +13,13 @@ You can insert any kind of content into it, and it will give you back a key that To demonstrate, you can use the plumbing command `hash-object`, which takes some data, stores it in your `.git` directory, and gives you back the key the data is stored as. First, you initialize a new Git repository and verify that there is nothing in the `objects` directory: ////////////////////////// -Git は連想記憶ファイル・システムです。素晴らしい。…で、それはどういう意味なのでしょう?それは、Git のコアの部分が単純なキーバリューから成り立つデータストアである、という意味です。`hash-object` という配管コマンドを使用することで、それを実際にお見せすることができます。そのコマンドはあるデータを取り出して、それを `.git` ディレクトリに格納し、そのデータが格納された場所を示すキーを返します。まずは、初期化された新しいGit レポジトリには `objects` ディレクトリが存在しないことを確認します。 +Git は内容アドレスファイルシステムです。 +素晴らしい。 +…で、それはどういう意味なのでしょう? +それは、Gitのコアの部分はシンプルなキー・バリュー型データストアである、という意味です。 +ここにはどんな種類のコンテンツでも格納でき、それに対応するキーが返されます。キーを使えば格納したコンテンツをいつでも取り出せます。 +これは `hash-object` という配管コマンドを使えば実際に確認できます。このコマンドはデータを受け取り、それを `.git` ディレクトリに格納し、そのデータを格納しているキーを返します。 +まずは、新しいGitリポジトリを初期化し、 `objects` ディレクトリ配下に何もないことを確認してみましょう。 [source,console] ---- @@ -31,7 +37,8 @@ $ find .git/objects -type f Git has initialized the `objects` directory and created `pack` and `info` subdirectories in it, but there are no regular files. Now, store some text in your Git database: ////////////////////////// -Git は `objects` ディレクトリを初期化して、その中に `pack` と `info` というサブディレクトリを作ります。しかし、ファイルはひとつも作られません。今から Git データベースに幾つかのテキストを格納してみます。 +Gitは `objects` ディレクトリを初期化して、その中に `pack` と `info` というサブディレクトリを作ります。しかし、ファイルはひとつも作られません。 +今からGitデータベースにテキストを幾つか格納してみます。 [source,console] ---- @@ -46,7 +53,11 @@ The output from the command is a 40-character checksum hash. This is the SHA-1 hash – a checksum of the content you're storing plus a header, which you'll learn about in a bit. Now you can see how Git has stored your data: ////////////////////////// -`-w` オプションは `hash-object` に、オブジェクトを格納するように伝えます。`-w` オプションを付けない場合、コマンドはただオブジェクトのキーが何かを伝えます。`--stdin` オプションは、標準入力からコンテンツを読み込むようにコマンドに伝えます。これを指定しない場合、`hash-object` はコマンドラインオプションの最後にファイルパスが指定されることを期待して動作します。コマンドを実行すると、40文字から成るチェックサムのハッシュ値が出力されます。これは、SHA-1ハッシュです。(後ほど知ることになりますが、これは格納するコンテンツにヘッダーを加えたデータに対するチェックサムです)これでGitがデータをどのようにして格納するかを知ることができました。 +`-w` オプションは、 `hash-object` にオブジェクトを格納するよう指示しています。`-w` オプションを付けない場合、コマンドはただオブジェクトのキーとなる文字列を返します。 +`--stdin` オプションは、標準入力からコンテンツを読み込むよう指示しています。これを指定しない場合、`hash-object` はコマンドラインオプションの最後にファイルパスが指定されることを期待して動作します。 +コマンドを実行すると、40文字から成るチェックサムのハッシュ値が出力されます。 +これは、SHA-1ハッシュです。すぐ後で説明しますが、これは格納するコンテンツにヘッダーを加えたデータに対するチェックサムです。 +これで、Gitがデータをどのようにして格納するか見ることができるようになりました。 [source,console] ---- @@ -59,14 +70,18 @@ You can see a file in the `objects` directory. This is how Git stores the content initially – as a single file per piece of content, named with the SHA-1 checksum of the content and its header. The subdirectory is named with the first 2 characters of the SHA-1, and the filename is the remaining 38 characters. ////////////////////////// -ひとつのファイルが `objects` ディレクトリの中にあります。このようして Git は、最初にコンテンツを格納します。ひとつの部分のコンテンツにつき 1ファイルで、コンテンツとそのヘッダーに対する SHA-1のチェックサムを用いたファイル名で格納します。サブディレクトリは、SHA-1ハッシュのはじめの2文字で名付けられ、残りの38文字でファイル名が決まります。 +`objects` ディレクトリの中にファイルがひとつあります。 +Gitはまずこのようにしてコンテンツを格納します。コンテンツ1つごとに1ファイルで、ファイル名はコンテンツとそのヘッダーに対するSHA-1チェックサムで決まります。 +SHA-1ハッシュのはじめの2文字がサブディレクトリの名前になり、残りの38文字がファイル名になります。 ////////////////////////// You can pull the content back out of Git with the `cat-file` command. This command is sort of a Swiss army knife for inspecting Git objects. Passing `-p` to it instructs the `cat-file` command to figure out the type of content and display it nicely for you: ////////////////////////// -`cat-file` コマンドを使って、コンテンツを Git の外に引き出すことができます。これは Git オブジェクトを調べることにおいて、`cat-file` は万能ナイフ(Swiss army knife)のような便利なコマンドです。`-p` オプションを付けると、`cat-file` コマンドはコンテンツのタイプをわかりやすく表示してくれます。 +`cat-file` コマンドを使うと、コンテンツをGitから取り出すことができます。 +このコマンドは、Gitオブジェクトを調べるための万能ナイフのようなものです。 +`-p` オプションを付けると、`cat-file` コマンドはコンテンツのタイプを判別し、わかりやすく表示してくれます。 [source,console] ---- @@ -80,7 +95,10 @@ You can also do this with content in files. For example, you can do some simple version control on a file. First, create a new file and save its contents in your database: ////////////////////////// -これであなたは Git にコンテンツを追加し、それを再び外に引き出すことができるようになりました。複数のファイルがあるコンテンツに対してもこれと同様のことを行うことができます。例えば、あるファイルに対して幾つかの簡単なバージョン管理行うことができます。まず、新規にファイルを作成し、あなたのデータベースにそのコンテンツを保存します。 +これで、Gitにコンテンツを追加したり、取り出したりできるようになりました。 +ファイルの内容に対しても、これと同様のことを行えます。 +例えば、あるファイルに対して簡単なバージョン管理を行うことができます。 +まず、新規にファイルを作成し、データベースにその内容を保存します。 [source,console] ---- @@ -92,7 +110,7 @@ $ git hash-object -w test.txt ////////////////////////// Then, write some new content to the file, and save it again: ////////////////////////// -それから、幾つか新しいコンテンツをそのファイルに書き込んで、再び保存します。 +それから、新しい内容をそのファイルに書き込んで、再び保存します。 [source,console] ---- @@ -104,7 +122,7 @@ $ git hash-object -w test.txt ////////////////////////// Your database contains the two new versions of the file as well as the first content you stored there: ////////////////////////// -データベースには、そこに格納した最初のコンテンツのバージョンに加えて、そのファイルの新しいバージョンが二つ追加されています。 +データベースには、最初に格納したコンテンツに加えて、上記のファイルのバージョン2つが新規に追加されています。 [source,console] ---- @@ -117,7 +135,7 @@ $ find .git/objects -type f ////////////////////////// Now you can revert the file back to the first version ////////////////////////// -これで、そのファイルを最初のバージョンに復帰(revert)することができます。 +これで、上記のファイルの変更を取り消して最初のバージョンに戻せるようになりました。 [source,console] ---- @@ -129,7 +147,7 @@ version 1 ////////////////////////// or the second version: ////////////////////////// -あるいは、二つ目のバージョンに。 +また、2つ目のバージョンにもできます。 [source,console] ---- @@ -143,7 +161,9 @@ But remembering the SHA-1 key for each version of your file isn't practical; plu This object type is called a blob. You can have Git tell you the object type of any object in Git, given its SHA-1 key, with `cat-file -t`: ////////////////////////// -しかし、それぞれのファイルのバージョンの SHA-1キーを覚えることは実用的ではありません。加えて、あなたはコンテンツのみを格納していてファイル名はシステム内に格納していません。このオブジェクトタイプはブロブ(blob)と呼ばれます。`cat-file -t` コマンドに SHA-1キーを渡すことで、あなたは Git 内にあるあらゆるオブジェクトのタイプを問い合わせることができます。 +しかし、それぞれのファイルのバージョンのSHA-1キーを覚えておくのは実用的ではありません。加えて、システムにはファイル名は格納されておらず、ファイルの内容のみが格納されています。 +このオブジェクトタイプはブロブ(blob)と呼ばれます。 +`cat-file -t` コマンドに SHA-1キーを渡すことで、あなたは Git 内にあるあらゆるオブジェクトのタイプを問い合わせることができます。 [source,console] ---- @@ -164,7 +184,11 @@ All the content is stored as tree and blob objects, with trees corresponding to A single tree object contains one or more tree entries, each of which contains a SHA-1 pointer to a blob or subtree with its associated mode, type, and filename. For example, the most recent tree in a project may look something like this: ////////////////////////// -次のタイプはツリーです。これは、ファイル名の格納の問題を解決して、さらに、あるグループに属するファイル群を一緒に格納します。Git がコンテンツを格納する方法は、UNIXのファイルシステムに似ていますが少し簡略されています。すべてのコンテンツはツリーとブロブのオブジェクトとして格納されます。ツリーは UNIXのディレクトリエントリーに対応しており、ブロブは幾分かは iノード またはファイルコンテンツに対応しています。1つのツリーオブジェクトは1つ以上のツリーエントリーを含んでいて、またそれらのツリーは、それに関連するモード、タイプ、そしてファイル名と一緒に、ブロブまたはサブツリーへの SHA-1ポインターを含んでいます。例えば、あるプロジェクトの最新のツリーはこのように見えるかもしれません。 +次のタイプはツリーです。これにより、ファイル名の格納の問題を解決して、さらに、複数のファイルをまとめて格納できるようになります。 +Git がコンテンツを格納する方法は、UNIXのファイルシステムに似ていますが少し簡略化されています。 +すべてのコンテンツはツリーオブジェクトまたはブロブオブジェクトとして格納されます。ツリーは UNIXのディレクトリエントリーと対応しており、ブロブはiノードやファイルコンテンツとほぼ対応しています。 +1つのツリーオブジェクトには1つ以上のツリーエントリーが含まれています。このツリーエントリーには、ブロブか、サブツリーとそれに関連するモード、タイプ、ファイル名へのSHA-1ポインターが含まれています。 +例えば、あるプロジェクトの最新のツリーはこのように見えるかもしれません。 [source,console] ---- @@ -178,7 +202,8 @@ $ git cat-file -p master^{tree} The `master^{tree}` syntax specifies the tree object that is pointed to by the last commit on your `master` branch. Notice that the `lib` subdirectory isn't a blob but a pointer to another tree: ////////////////////////// -`master^{tree}` のシンタックスは、`master` ブランチ上での最後のコミットによってポイントされたツリーオブジェクトを示します。`lib` サブディレクトリがブロブではなく、別のツリーへのポインタであることに注意してください。 +`master^{tree}` のシンタックスは、`master` ブランチ上での最後のコミットが指しているツリーオブジェクトを示します。 +`lib` サブディレクトリはブロブではなく、別のツリーへのポインタであることに注意してください。 [source,console] ---- @@ -189,7 +214,7 @@ $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 ////////////////////////// Conceptually, the data that Git is storing is something like this: ////////////////////////// -概念的に、Git が格納するデータは次のようなものです。 +概念的には、Gitが格納するデータは次のようなものです。 ////////////////////////// .Simple version of the Git data model. @@ -207,13 +232,14 @@ You use this command to artificially add the earlier version of the test.txt fil You must pass it the `--add` option because the file doesn't yet exist in your staging area (you don't even have a staging area set up yet) and `--cacheinfo` because the file you're adding isn't in your directory but is in your database. Then, you specify the mode, SHA-1, and filename: ////////////////////////// -独自のツリーを作ることもかなり簡単に行えます。Git は通常、ステージングエリアもしくはインデックスの状態を取得することによってツリーを作成し、 -そこから一連のツリーオブジェクトを書き込みます。そのため、ツリーオブジェクトを作るには、まず幾つかのファイルをステージングしてインデックスをセットアップしなければなりません。 -test.txt ファイルの最初のバージョンである単一エントリーのインデックスを作るには、`update-index` という配管コマンドを使います。 -前バージョンの test.txt ファイルを新しいステージングエリアに人為的に追加するにはこのコマンドを使います。 -ファイルはまだステージングエリアには存在しない(未だステージングエリアをセットアップさえしていない)ので、`--add` オプションを付けなければなりません。 +自前でツリーを作るのも非常に簡単です。 +Gitは通常、ステージングエリアやインデックスの状態を取得してツリーを作成し、そのツリーをもとに一連のツリーオブジェクトを書き込みます。 +そのため、ツリーオブジェクトを作るには、まずファイルをステージングしてインデックスを作成しなければなりません。 +単一のエントリー – ここではtest.txtファイルの最初のバージョン – からインデックスを作るには、`update-index` という配管コマンドを使います。 +このコマンドは、前のバージョンのtest.txtファイルをあえて新しいステージングエリアに追加する際に使用します。 +ファイルはまだステージングエリアには存在しない(まだステージングエリアをセットアップさえしていない)ので、`--add` オプションを付けなければなりません。 また、追加しようとしているファイルはディレクトリには無くデータベースにあるので、`--cacheinfo`オプションを付ける必要があります。 -その次に、モードと SHA-1、そしてファイル名を指定します。 +その次に、モード、SHA-1、ファイル名を指定します。 [source,console] ---- @@ -226,13 +252,16 @@ In this case, you're specifying a mode of `100644`, which means it's a normal fi Other options are `100755`, which means it's an executable file; and `120000`, which specifies a symbolic link. The mode is taken from normal UNIX modes but is much less flexible – these three modes are the only ones that are valid for files (blobs) in Git (although other modes are used for directories and submodules). ////////////////////////// -この例では、`100644` のモードを指定しています。これは、それが通常のファイルであることを意味します。他には、実行可能ファイルであることを意味する `100755` や、シンボリックリンクであることを示す `120000` のオプションがあります。このモードは通常の UNIX モードから取り入れた概念ですが融通性はもっと劣ります。これら三つのモードは、(他のモードはディレクトリとサブモジュールに使用されますが)Git のファイル(ブロブ)に対してのみ有効です。 +この例では、`100644` のモードを指定しています。これは、それが通常のファイルであることを意味します。 +他に指定できるモードとしては、実行可能ファイルであることを意味する `100755` や、シンボリックリンクであることを示す `120000` があります。 +このモードは通常の UNIX モードから取り入れた概念ですが、それほどの柔軟性はありません。Git中のファイル(ブロブ)に対しては、上記3つのモードのみが有効です(ディレクトリとサブモジュールに対しては他のモードも使用できます)。 ////////////////////////// Now, you can use the `write-tree` command to write the staging area out to a tree object. No `-w` option is needed – calling `write-tree` automatically creates a tree object from the state of the index if that tree doesn't yet exist: ////////////////////////// -これであなたは `write-tree` コマンドを使って、ステージングエリアをツリーオブジェクトに書き出すことができます。`-w` オプションは一切必要とされません。`write-tree` コマンドを呼ぶことで、ツリーがまだ存在しない場合に、自動的にインデックスの状態からツリーオブジェクトを作ります。 +これで、 `write-tree` コマンドを使って、ステージングエリアをツリーオブジェクトに書き出せるようになりました。 +`-w` オプションは不要です。`write-tree` コマンドを呼ぶと、ツリーがまだ存在しない場合には、インデックスの状態をもとに自動的にツリーオブジェクトが作られます。 [source,console] ---- @@ -245,7 +274,7 @@ $ git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579 ////////////////////////// You can also verify that this is a tree object: ////////////////////////// -また、これがツリーオブジェクトであることを検証することができます。 +また、これがツリーオブジェクトであることを検証できるようになりました。 [source,console] ---- @@ -256,7 +285,7 @@ tree ////////////////////////// You'll now create a new tree with the second version of test.txt and a new file as well: ////////////////////////// -これから、二つ目のバージョンの test.txt に新しいファイルを加えて新しくツリーを作ります。 +今度は、2つめのバージョンのtest.txtと、新規作成したファイルから、新しくツリーを作ります。 [source,console] ---- @@ -269,7 +298,8 @@ $ git update-index --add new.txt Your staging area now has the new version of test.txt as well as the new file new.txt. Write out that tree (recording the state of the staging area or index to a tree object) and see what it looks like: ////////////////////////// -これでステージングエリアには、new.txt という新しいファイルに加えて、新しいバージョンの test.txt を持つようになります。(ステージングエリアまたはインデックスの状態を記録している)そのツリーを書き出してみると、以下のように見えます。 +これでステージングエリアには、new.txtという新しいファイルに加えて、新しいバージョンのtest.txtも登録されました。 +このツリーを書き出して(ステージングエリアまたはインデックスの状態をツリーオブジェクトとして記録して)、どのようになったか見てみましょう。 [source,console] ---- @@ -286,7 +316,10 @@ Just for fun, you'll add the first tree as a subdirectory into this one. You can read trees into your staging area by calling `read-tree`. In this case, you can read an existing tree into your staging area as a subtree by using the `--prefix` option to `read-tree`: ////////////////////////// -このツリーは両方のファイルエントリを持っていて、さらに、test.txt の SHA-1ハッシュは最初の文字(`1f7a7a`)から ``バージョン2'' の SHA-1ハッシュとなっていることに注意してください。ちょっと試しに、最初のツリーをサブディレクトリとしてこの中の1つに追加してみましょう。`read-tree` を呼ぶことで、ステージングエリアの中にツリーを読み込むことができます。このケースでは、`--prefix` オプションを付けて `read-tree` コマンド使用することで、ステージングエリアの中に既存のツリーを、サブツリーとして読み込むことができます。 +このツリーに両方のファイルエントリがあること、また、test.txtのSHA-1が先ほどの ``version 2'' のSHA-1(`1f7a7a`)であることに注意してください。 +ちょっと試しに、最初のツリーをサブディレクトリとしてこの中に追加してみましょう。 +`read-tree` を呼ぶことで、ステージングエリアの中にツリーを読み込むことができます。 +このケースでは、`--prefix` オプションを付けて `read-tree` コマンドを使用することで、ステージングエリアの中に、既存のツリーをサブツリーとして読み込むことができます。 [source,console] ---- @@ -303,14 +336,15 @@ $ git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614 If you created a working directory from the new tree you just wrote, you would get the two files in the top level of the working directory and a subdirectory named `bak` that contained the first version of the test.txt file. You can think of the data that Git contains for these structures as being like this: ////////////////////////// -先ほど書き込んだ新しいツリーから作業ディレクトリを作っていれば、二つのファイルが作業ディレクトリのトップレベルに見つかり、また、最初のバージョンの test.txt ファイルが含まれている `bak` という名前のサブディレクトリが見つかります。これらの構造のために Git がデータをどのように含めているかは、次のようにイメージすることができます。 +先ほど書き込んだ新しいツリーから作業ディレクトリを作っていれば、作業ディレクトリの直下にファイルが2つと、最初のバージョンのtest.txtファイルが含まれている `bak` という名前のサブディレクトリが入ります。 +このような構成に対し、Gitが格納するデータのイメージは次のようになります。 ////////////////////////// .The content structure of your current Git data. image::images/data-model-2.png[The content structure of your current Git data.] ////////////////////////// -.現在のGitデータのコンテンツ構造 -image::images/data-model-2.png[現在のGitデータのコンテンツ構造] +.現在のGitデータの内容の構成 +image::images/data-model-2.png[現在のGitデータの内容の構成] [[_git_commit_objects]] ////////////////////////// @@ -323,13 +357,16 @@ You have three trees that specify the different snapshots of your project that y You also don't have any information about who saved the snapshots, when they were saved, or why they were saved. This is the basic information that the commit object stores for you. ////////////////////////// -追跡(track)したいと思うプロジェクトの異なるスナップショットを特定するためのツリーが三つありますが、前の問題が残っています。スナップショットを呼び戻すためには3つすべての SHA-1 の値を覚えなければならない、という問題です。さらに、あなたはそれらのスナップショットがいつ、どのような理由で、誰が保存したのかについての情報を一切持っておりません。これはコミットオブジェクトがあなたのために保持する基本的な情報です。 +追跡したいプロジェクトに対し、それぞれ異なる内容のスナップショットを示すツリー3つができました。ですが、各スナップショットを呼び戻すには3つのSHA-1の値すべてを覚えておかなければならない、という以前からの問題は残ったままです。 +さらに、そのスナップショットを誰が、いつ、どのような理由で保存したのかについての情報が一切ありません。 +これはコミットオブジェクトに保存される基本的な情報です。 ////////////////////////// To create a commit object, you call `commit-tree` and specify a single tree SHA-1 and which commit objects, if any, directly preceded it. Start with the first tree you wrote: ////////////////////////// -コミットオブジェクトを作成するには、単一ツリーの SHA-1 と、もしそれに直に先行して作成されたコミットオブジェクトがあれば、それらを指定して `commit-tree` を呼びます。あなたが書き込んだ最初のツリーから始めましょう。 +コミットオブジェクトを作成するには、ツリーのSHA-1を1つと、もしそれの直前に来るコミットオブジェクトがあれば、それらを指定して `commit-tree` を呼びます。 +最初に書き込んだツリーから始めましょう。 [source,console] ---- @@ -340,7 +377,7 @@ fdf4fc3344e67ab068f836878b6c4951e3b15f3d ////////////////////////// Now you can look at your new commit object with `cat-file`: ////////////////////////// -これで `cat-file` コマンドを呼んで新しいコミットオブジェクトを見ることができます。 +これで、`cat-file` コマンドを使って、新しいコミットオブジェクトを見られるようになりました。 [source,console] ---- @@ -355,12 +392,12 @@ first commit ////////////////////////// The format for a commit object is simple: it specifies the top-level tree for the snapshot of the project at that point; the author/committer information (which uses your `user.name` and `user.email` configuration settings and a timestamp); a blank line, and then the commit message. ////////////////////////// -コミットオブジェクトの形式はシンプルです。それはプロジェクトのその時点のスナップショットに対して、トップレベルのツリーを指定します。その時点のスナップショットには、作者(author)/コミッター(committer)の情報(`user.name` および `user.email` の設定と現在のタイムスタンプを使用しています)、ブランクライン、そしてコミットメッセージが含まれます。 +コミットオブジェクトの形式はシンプルです。その内容は、コミットが作成された時点のスナップショットのトップレベルのツリー、作者とコミッターの情報(`user.name` および `user.email` の設定と現在のタイムスタンプを使用します)、空行、そしてコミットメッセージとなっています。 ////////////////////////// Next, you'll write the other two commit objects, each referencing the commit that came directly before it: ////////////////////////// -次に、あなたは二つのコミットオブジェクトを書き込みます。各コミットオブジェクトはその直前に来たコミットを参照しています。 +次に、コミットオブジェクトを新たに2つ書き込みます。各コミットオブジェクトはその直前のコミットを参照しています。 [source,console] ---- @@ -374,7 +411,8 @@ $ echo 'third commit' | git commit-tree 3c4e9c -p cac0cab Each of the three commit objects points to one of the three snapshot trees you created. Oddly enough, you have a real Git history now that you can view with the `git log` command, if you run it on the last commit SHA-1: ////////////////////////// -三つのコミットオブジェクトは、それぞれ、あなたが作成した三つのスナップショットのツリーのひとつを指し示しています。面白いことに、あなたは本物のGitヒストリーを持っており、`git log` コマンドによってログをみることができます。もしも最後のコミットの SHA-1ハッシュを指定して実行すると、 +3つのコミットオブジェクトは、それぞれ、これまでに作成した3つのスナップショットのツリーのひとつを指しています。 +奇妙なことに、これで本物のGitヒストリーができており、`git log` コマンドによってログを表示できます。最後のコミットのSHA-1ハッシュを指定して実行すると…… [source,console] ---- @@ -415,7 +453,11 @@ This is essentially what Git does when you run the `git add` and `git commit` co These three main Git objects – the blob, the tree, and the commit – are initially stored as separate files in your `.git/objects` directory. Here are all the objects in the example directory now, commented with what they store: ////////////////////////// -驚くべきことです。あなたはフロントエンドのコマンドを利用せずに、ただ下位レベルのオペレーションを行っただけで Git ヒストリーを形成したのです。これは `git add` コマンドと `git commit` コマンドを実行するときに Git が行う本質的なことなのです。それは変更されたファイルに対応して、ブロブを格納し、インデックスを更新し、ツリーを書き出します。そして、トップレベルのツリーとそれらの直前に来たコミットを参照するコミットオブジェクトを書きます。これらの三つの主要な Git オブジェクト - ブロブとツリーとコミットは、`.git/object` ディレクトリに分割されたファイルとして最初に格納されます。こちらは、例のディレクトリに今あるすべてのオブジェクトであり、それらが何を格納しているのかコメントされています。 +素晴らしい。 +フロントエンドのコマンドを利用せずに、低レベルのオペレーションだけでGitの歴史を作り上げたのです。 +これは、本質的に `git add` コマンドと `git commit` コマンドを実行するときにGitが行っていることと同じです。変更されたファイルに対応するブロブを格納し、インデックスを更新し、ツリーを書き出し、トップレベルのツリーと、その直前のコミットを参照するコミットオブジェクトとを書き出しています。 +これらの3つの主要な Git オブジェクト – ブロブとツリーとコミット – は、まずは個別のファイルとして `.git/object` ディレクトリに格納されます。 +現在、サンプルのディレクトリにあるすべてのオブジェクトを以下に示します。コメントは、それぞれ何を格納しているのかを示します。 [source,console] ---- @@ -435,14 +477,14 @@ $ find .git/objects -type f ////////////////////////// If you follow all the internal pointers, you get an object graph something like this: ////////////////////////// -もしすべての内部のポインタを辿ってゆけば、次のようなオブジェクトグラフを得られます。 +すべての内部のポインタを辿ってゆけば、次のようなオブジェクトグラフが得られます。 ////////////////////////// .All the objects in your Git directory. image::images/data-model-3.png[All the objects in your Git directory.] ////////////////////////// -.Gitレポジトリ内のすべてのオブジェクト -image::images/data-model-3.png[Gitレポジトリ内のすべてのオブジェクト] +.Gitリポジトリ内のすべてのオブジェクト +image::images/data-model-3.png[Gitリポジトリ内のすべてのオブジェクト] ////////////////////////// ==== Object Storage @@ -454,12 +496,14 @@ We mentioned earlier that a header is stored with the content. Let's take a minute to look at how Git stores its objects. You'll see how to store a blob object – in this case, the string ``what is up, doc?'' – interactively in the Ruby scripting language. ////////////////////////// -ヘッダはコンテンツと一緒に格納されることを、以前に述べました。少し時間を割いて、Git がどのようにしてオブジェクトを格納するのかを見ていきましょう。あなたはブロブオブジェクトがどのように格納されるのかを見ることになるでしょう。このケースでは ``what is up, doc?'' という文字列が Rubyスクリプト言語の中で対話的に格納されます。 +ヘッダはコンテンツと一緒に格納されることを、以前に述べました。 +ここでは少し時間を割いて、Gitがどのようにオブジェクトを格納するのかを見ていきましょう。 +以降では、ブロブオブジェクト – ここでは ``what is up, doc?'' という文字列 – をRuby言語を使って対話的に格納する方法を説明します。 ////////////////////////// You can start up interactive Ruby mode with the `irb` command: ////////////////////////// -`irb` コマンドを使って対話的な Rubyモードを開始します。 +`irb` コマンドで、対話モードでRubyを起動します。 [source,console] ---- @@ -472,7 +516,8 @@ $ irb Git constructs a header that starts with the type of the object, in this case a blob. Then, it adds a space followed by the size of the content and finally a null byte: ////////////////////////// -Git はオブジェクトタイプで開始するヘッダを構成します。このケースではブロブのタイプです。そして、コンテンツのサイズに従ってスペースを追加して、最後にヌルバイトを追加します。 +Gitがヘッダを構築する際には、まず初めにオブジェクトのタイプを表す文字列が来ます。この場合はblobです。 +次に、スペースに続いてコンテンツのサイズ、最後にヌルバイトが追加されます。 [source,console] ---- @@ -484,7 +529,8 @@ Git はオブジェクトタイプで開始するヘッダを構成します。 Git concatenates the header and the original content and then calculates the SHA-1 checksum of that new content. You can calculate the SHA-1 value of a string in Ruby by including the SHA1 digest library with the `require` command and then calling `Digest::SHA1.hexdigest()` with the string: ////////////////////////// -Git はヘッダとオリジナルのコンテンツとを結合して、その新しいコンテンツの SHA-1チェックサムを計算します。Rubyスクリプト内に書かれた文字列のSHA-1のハッシュ値は、`require` を使用して SHA1ダイジェストライブラリをインクルードし、文字列を引数にして `Digest::SHA1.hexdigest()` 関数を呼ぶことで求めることができます。 +Gitはこのヘッダと元々のコンテンツとを結合して、その新しいコンテンツのSHA-1チェックサムを計算します。 +Rubyでは、文字列のSHA-1のハッシュ値は、`require` を使用してSHA1ダイジェストライブラリをインクルードし、文字列を引数にして `Digest::SHA1.hexdigest()` 関数を呼ぶことで求められます。 [source,console] ---- @@ -500,7 +546,8 @@ Git はヘッダとオリジナルのコンテンツとを結合して、その Git compresses the new content with zlib, which you can do in Ruby with the zlib library. First, you need to require the library and then run `Zlib::Deflate.deflate()` on the content: ////////////////////////// -Gitは zlib を用いて新しいコンテンツを圧縮します。Rubyにある zlibライブラリをインクルードして使用します。まず、require を使用して zlib ライブラリをインクルードし、コンテンツに対して `Zlib::Deflate.deflate()` を実行します。 +Gitはzlibを用いてこの新しいコンテンツを圧縮します。Rubyではzlibライブラリをインクルードすれば同じことが行えます。 +まず、requireを使用してzlibライブラリをインクルードし、コンテンツに対して `Zlib::Deflate.deflate()` を実行します。 [source,console] ---- @@ -516,7 +563,10 @@ You'll determine the path of the object you want to write out (the first two cha In Ruby, you can use the `FileUtils.mkdir_p()` function to create the subdirectory if it doesn't exist. Then, open the file with `File.open()` and write out the previously zlib-compressed content to the file with a `write()` call on the resulting file handle: ////////////////////////// -最後に、zlibで圧縮された(zlib-deflated)コンテンツをディスク上のオブジェクトに書き込みます。オブジェクトの書き込み先のパスを決定します(SHA-1ハッシュ値の最初の2文字はサブディレクトリの名前で、残りの38文字はそのディレクトリ内のファイル名になります)。Rubyでは、`FileUtils.mkdir_p()` 関数を使用して(存在しない場合に)サブディレクトリを作成することができます。そして、`File.open()` によってファイルを開いて、前に zlib で圧縮された(zlib-compressed)コンテンツをファイルに書き出します。ファイルへの書き出しは、開いたファイルのハンドルに対して `write()` を呼ぶことで行います。 +最後に、zlibでdeflate圧縮されたコンテンツをディスク上のオブジェクトに書き込みます。 +まず、オブジェクトを書き出す先のパスを決定します(SHA-1ハッシュ値の最初の2文字はサブディレクトリの名前で、残りの38文字はそのディレクトリ内のファイル名になります)。 +Rubyでは、サブディレクトリが存在しない場合、 `FileUtils.mkdir_p()` 関数で作成できます。 +そして、`File.open()` によってファイルを開いて、前にzlibで圧縮したコンテンツをファイルに書き出します。ファイルへの書き出しは、開いたファイルのハンドルに対して `write()` を呼ぶことで行います。 [source,console] ---- @@ -535,4 +585,6 @@ That's it – you've created a valid Git blob object. All Git objects are stored the same way, just with different types – instead of the string blob, the header will begin with commit or tree. Also, although the blob content can be nearly anything, the commit and tree content are very specifically formatted. ////////////////////////// -これで終わりです。あなたは妥当な Git ブロブオブジェクトを作りました。ただタイプが異なるだけで、Git オブジェクトはすべて同じ方法で格納されます。ブロブの文字列ではない場合には、ヘッダはコミットまたはツリーから始まります。また、ブロブのコンテンツはほぼ何にでもなれるのに対して、コミットとツリーのコンテンツはかなり特定的に形式付けられています。 +これだけです。これで、正当なGitブロブオブジェクトが出来上がりました。 +Gitオブジェクトはすべて同じ方法で格納されますが、オブジェクトのタイプだけは様々で、ヘッダーが blobという文字列ではなく、commitやtreeという文字列で始まることもあります。 +また、オブジェクトタイプがブロブの場合、コンテンツはほぼ何でもよいですが、コミットとツリーの場合、コンテンツは非常に厳密に形式が定められています。