#Git原理の簡単な理解
13286 ワード
総説:Gitは根本的にコンテンツアドレス(content-addressable)ファイルシステムであり、その上にVCSユーザーインタフェースを提供している.
-
操作によって一歩一歩理解する
1.ファイルディレクトリ構造を表示するための
インストール後、任意のディレクトリの下に
2.クリーンなフォルダを新規作成し、
現在のファイルの上位ディレクトリに戻りたい場合、通常は
3.現在のディレクトリで
隠しファイル
4.cdは
5.
私たちが追加した内容はこのファイルに保存されています.
6.
この書類の内容は、私たちの
私たちがcommitを行う場合、プロジェクトディレクトリのファイルの存在状況は1つのファイル
これが、commit記述ファイルで発見されたルートディレクトリを指すファイルです.
7.新しいファイルを追加し続け、
3つ以上のファイルが出てきて、ファイルの内容を手に入れると、以前の最初のファイルに保存されていたものと同じものが見えます.1つは
最初のcommitは親ノードがないのでparentはありませんが、その後のcommitは親ノードがあるのでparentという行があります.
8.振り返ってHEAD、refsの2つのファイルについて話します.HEADは現在のブランチを指していることはよく知られていますが、それはどのように指しているのか、彼の内容を見てみるとわかります.HEADは本質的に1つのファイルです!以上のものはすべてファイルです!!
HEADの内容はファイルパスなので、HEADが現在のブランチを指しているのではなく、ファイルのパスを指しています.このファイルパスに基づいてファイルの内容を見てみましょう.
このパスの下のファイルの内容は、2回目のcommitのファイル名なので、正確には、このファイルは現在のブランチの現在のcommitを指していますが、HEADファイルの内容はこのファイルです.ファイルがロールバック操作を行うと、
9.新しいブランチ
refs/headersの下にdevelopというファイルが1つ増えていることがわかります.developファイルの内容を取得し、masterの2回目のcommitコンテンツのファイルを指します.
したがって、現在のブランチに基づいて新しいブランチを作成するのは、本質的には1つのファイルだけであり、このファイルの内容は、分割が作成されたときに最新のcommitを指すだけです.ブランチを作成するコストは非常に小さいです.
10.この時点でブランチが
-
操作によって一歩一歩理解する
1.ファイルディレクトリ構造を表示するための
tree
ツールをインストールし、Gitの学習理解に役立ちます.brew install tree
インストール後、任意のディレクトリの下に
tree
コマンドを入力すると、ディレクトリがツリー構造で表示され、階層関係が一目瞭然になります.2.クリーンなフォルダを新規作成し、
ls -a
コマンドを実行してすべてのファイル(非表示ファイルを含む)を表示します.2つのファイルが表示されます.. ..
現在のファイルの上位ディレクトリに戻りたい場合、通常は
cd ..
コマンドが使用されますが、ここには..
という隠しファイルがあるので、..
は実は上位ディレクトリの識別ファイルであると理解できます.3.現在のディレクトリで
git init
コマンドを実行し、ls -a
でファイルの状況を確認します.. .. .git
隠しファイル
.git
が1つ多く出てきて、すべてのGitが格納して操作した内容がこのディレクトリの下にあります.ライブラリをバックアップまたはコピーする場合は、基本的にこのディレクトリを他の場所にコピーすればいいです.4.cdは
.git
ファイルに入り、tree
コマンドで現在のディレクトリ構造を表示します.いくつかのファイルの大まかな役割について簡単な注釈をしました.次に重点的に展開するファイルには、*番号のタグを付けました.$ tree
.
├── HEAD //* ,
├── config //
├── description // GitWeb ,
├── hooks //
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ └── update.sample
├── info
│ └── exclude
├── objects //*
│ ├── info
│ └── pack
└── refs //* ( ) ,
├── heads
└── tags
8 directories, 14 files
5.
git add
の操作を理解する:開発プロセスをシミュレートし、あなたのプロジェクトディレクトリの下で新しいファイルを作成します.ここではREADME.md
を例に挙げます.作成後、ファイルに任意の内容を書き込み、git add .
操作を実行します.このとき、.git
ディレクトリに入り、tree
コマンドを実行します.$ tree
.
├── HEAD
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── objects
│ ├── d0
│ │ └── d37ed92ba0227dc7c3b9a5cb2a8bfa6a04a6f1
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
9 directories, 16 files
objects
ディレクトリの下に多くのものが出ていることがわかります.これは私たちのさっきのgit add .
操作によって生成されました.では、これらの書類は何を表していますか.実はこのファイルはGitがコンテンツごとに生成したファイルで、そのコンテンツとヘッダ情報のSHA-1チェックサムを取得し、そのチェックサムの最初の2文字を名前とするサブディレクトリを作成し、残り38文字をファイル名として(サブディレクトリの下に保存する).簡単に言えばgitはアルゴリズムによって私たちが提出した内容を計算して一連の数字を得て、それから数字の上位2桁を1つのディレクトリ名として、残りの文字列をファイル名とします.ファイルの内容を確認します.cat-fileコマンドを使用できます.このコマンドはGitオブジェクトのスイス軍刀を表示します.転送-pパラメータは、このコマンドにデータの内容のタイプを出力させることができます.完全なファイル名はディレクトリ名+ファイル名であることに注意してください.$ git cat-file -p d0d37ed92ba0227dc7c3b9a5cb2a8bfa6a04a6f1
#GitTest
私たちが追加した内容はこのファイルに保存されています.
6.
git commit
を理解する:操作したばかりの上で、git commit -m
の操作を実行し、同様に.git
のディレクトリ構造を観察し、私が提出した説明は「.$ tree
.
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 5f
│ │ └── 3a2c5612b3687a8963fe76e46305b0c7ba5724
│ ├── cf
│ │ └── 0359c6428293e0b717f02292ef191ccc590592
│ ├── d0
│ │ └── d37ed92ba0227dc7c3b9a5cb2a8bfa6a04a6f1
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
14 directories, 22 files
objects
ディレクトリには2つのファイルが追加されています.$ git cat-file -p 5f3a2c5612b3687a8963fe76e46305b0c7ba5724
tree cf0359c6428293e0b717f02292ef191ccc590592
author liuyiyi <liuyiyi@lyydeMacBook-Pro.local> 1503989030 +0800
committer liuyiyi <liuyiyi@lyydeMacBook-Pro.local> 1503989030 +0800
first commit
この書類の内容は、私たちの
git commit -m
の説明情報です.彼はtree cf0359c6428293e0b717f02292ef191ccc590592
を持っていることに注意してください.これは今回提出したプロジェクトのルートディレクトリを指しています.どういう意味か見てみましょう.$ git cat-file -p cf0359c6428293e0b717f02292ef191ccc590592
100644 blob d0d37ed92ba0227dc7c3b9a5cb2a8bfa6a04a6f1 GitTestREADME.md
私たちがcommitを行う場合、プロジェクトディレクトリのファイルの存在状況は1つのファイル
GitTestREADME.md
しかないので、指定されたバージョンのコードロールバックを行うと、この値に基づいて当時のルートディレクトリのファイルの存在状態を戻します.残りのファイルは何ですか.$ git cat-file -p cf0359c6428293e0b717f02292ef191ccc590592
100644 blob d0d37ed92ba0227dc7c3b9a5cb2a8bfa6a04a6f1 GitTestREADME.md
これが、commit記述ファイルで発見されたルートディレクトリを指すファイルです.
7.新しいファイルを追加し続け、
git add.
とgit commit -m
の操作をもう一度実行します.1つのコマンドが指示されたら、.git
ファイルの変化状況を観察します.ここでは最終的な結果状態をリストします.プロセスは省略します.$ tree
.
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 58
│ │ └── 7a55b8f052d0a74bd592ffe7c8c5ff8ccc06c5
│ ├── 5f
│ │ └── 3a2c5612b3687a8963fe76e46305b0c7ba5724
│ ├── 92
│ │ └── a36d18afcce6bdda094c8360551051695fc842
│ ├── c9
│ │ └── c50f0b74a03f5be47d97770a2d11e23983d425
│ ├── cf
│ │ └── 0359c6428293e0b717f02292ef191ccc590592
│ ├── d0
│ │ └── d37ed92ba0227dc7c3b9a5cb2a8bfa6a04a6f1
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
17 directories, 25 files
3つ以上のファイルが出てきて、ファイルの内容を手に入れると、以前の最初のファイルに保存されていたものと同じものが見えます.1つは
git add
が提出した内容で、1つはgit commit -m
の内容で、1つは現在のルートディレクトリです.注意しなければならないのは、このgit commit -m
の内容が保存されているディレクトリで、それは最初のcommitといくつかの違いがあります.$ git cat-file -p 92a36d18afcce6bdda094c8360551051695fc842
tree 587a55b8f052d0a74bd592ffe7c8c5ff8ccc06c5
parent 5f3a2c5612b3687a8963fe76e46305b0c7ba5724
author liuyiyi <liuyiyi@lyydeMacBook-Pro.local> 1503991626 +0800
committer liuyiyi <liuyiyi@lyydeMacBook-Pro.local> 1503991626 +0800
second commit
parent 5f3a2c5612b3687a8963fe76e46305b0c7ba5724
が1つ増えて、字面からどういう意味か理解することができて、その前のcommitを指して、前のノードと理解することができて、証明することができます:$ git cat-file -p 5f3a2c5612b3687a8963fe76e46305b0c7ba5724
tree cf0359c6428293e0b717f02292ef191ccc590592
author liuyiyi <liuyiyi@lyydeMacBook-Pro.local> 1503989030 +0800
committer liuyiyi <liuyiyi@lyydeMacBook-Pro.local> 1503989030 +0800
first commit
最初のcommitは親ノードがないのでparentはありませんが、その後のcommitは親ノードがあるのでparentという行があります.
8.振り返ってHEAD、refsの2つのファイルについて話します.HEADは現在のブランチを指していることはよく知られていますが、それはどのように指しているのか、彼の内容を見てみるとわかります.HEADは本質的に1つのファイルです!以上のものはすべてファイルです!!
vim HEAD
ref: refs/heads/master
HEADの内容はファイルパスなので、HEADが現在のブランチを指しているのではなく、ファイルのパスを指しています.このファイルパスに基づいてファイルの内容を見てみましょう.
vim refs/heads/master
92a36d18afcce6bdda094c8360551051695fc842
このパスの下のファイルの内容は、2回目のcommitのファイル名なので、正確には、このファイルは現在のブランチの現在のcommitを指していますが、HEADファイルの内容はこのファイルです.ファイルがロールバック操作を行うと、
refs/heads/master
のファイルの値が変更され、ロールバックしたcommitになります.9.新しいブランチ
develop
を作成し、.git
ファイルディレクトリの変化を観察する.└── refs
├── heads
│ ├── develop
│ └── master
└── tags
refs/headersの下にdevelopというファイルが1つ増えていることがわかります.developファイルの内容を取得し、masterの2回目のcommitコンテンツのファイルを指します.
vim refs/heads/develop
92a36d18afcce6bdda094c8360551051695fc842
したがって、現在のブランチに基づいて新しいブランチを作成するのは、本質的には1つのファイルだけであり、このファイルの内容は、分割が作成されたときに最新のcommitを指すだけです.ブランチを作成するコストは非常に小さいです.
10.この時点でブランチが
develop
に切り替わると、HEADの変化が観察され、HEADコンテンツがどのように変化し、ファイルコンテンツがrefs/heads/develop
となる経路、すなわち現在のブランチdevelop
を指すかが推測される.