私はGitHubには、それを行う方法を正確に知っているが、ここで可能な方法ではありません。 gitがデータを格納する方法の知識が必要です。
簡単な答えは、repos can shareobjects
データベースですが、それぞれには独自の参照があります。
概念実証のためにローカルでシミュレーションすることもできます。全店舗
objects/
サブディレクトリ、:裸のレポのディレクトリで が動作するレポのために最低限の3つのものがある(または.git/
サブディレクトリにそれは裸ではない場合)オブジェクト(コミット、ツリー、ブロブなど)。それらは、オブジェクトのハッシュと同じ名前を持つファイルとして、または.pack
ファイルに個別に格納されます。 refs/heads/master
その内容のような、単純なファイルを格納する
refs/
サブディレクトリには、それが参照するオブジェクトのハッシュです。
HEAD
ファイル(現在のコミットは何ですか)。私たちはある意味します - その値は、生のハッシュ(私たちはどんな名前の枝に含まれていない、つまり切り離さヘッドに相当)または、例えばref: refs/heads/master
の実際のハッシュを見つけることができREF(へのテキストリンクのいずれかでありますブランチmaster
)
Githubで元の(フォークではない)レポorig
を作成したとしましょう。
は、ローカル我々は上記のGitHubのサーバで起こることを想像
$ git init --bare github_orig
を行い、シミュレートします。今は空のgithubリポジトリがあります。我々はhttps://github...
を使用する実際の生活の中ではなく、github_orig
もちろん
$ git clone github_orig local_orig
:その後、我々は我々自身のPCから、我々はgithubのレポのクローンを作成することを想像してみてください。今我々はlocal_orig
にgithubレポをクローンしました。このgithub_orig
のobject
dirの後
$ cd local_orig/
$ echo zzz > file
$ git add file
$ git commit -m initial
$ git push
$ cd ..
、オブジェクトをコミットfile
し、一本の木のオブジェクトに対して1つのBLOBオブジェクトを、当社のプッシュが含まれます。 refs/heads/master
ファイルにはコミットハッシュが含まれます。
は今、誰かがFork
ボタンを押したときの画像は何が起こっていることができましょう。我々はHEAD
とrefs
をコピー
$ mkdir github_fork
$ cd github_fork/
$ cp ../github_orig/HEAD .
$ cp -r ../github_orig/refs .
$ ln -s ../github_orig/objects
$ cd ..
お知らせが、我々はobjects
ためシンボリックリンクにします 私たちは手でGitのレポが、を作成します。我々が見ることができるようにフォークは非常に安いです。たとえ数十の分岐を持っていても、それぞれが単純な16進ハッシュ(40バイト)を含むrefs/heads
ディレクトリのファイルに過ぎません。 objects
の場合、元のオブジェクトディレクトリにのみリンクします。何もコピーしません!私たちはからクローンレポには独自のobjects
が、リンクを持っていませんが
$ git clone github_fork local_fork
$ cd local_fork
$ # ls
.git/ file
我々は、我々がクローニングに成功していることがわかります。
は、今、私たちは、ユーザがクローンローカルフォークレポ、フォークを作ることをシミュレート元のレポのそれに。
分岐してコミットし、github_fork
にプッシュすることができます。オブジェクトはobjects
ディレクトリにプッシュされます。このディレクトリはgithub_orig
と同じです!しかしrefs
とHEAD
は変更され、github_orig
のものと一致しなくなります。
したがって、同じフォークツリーに属するすべてのreposは共通オブジェクトプールを共有し、各repoには独自の参照が含まれています。自分のフォークされたリポジトリにコミットする人は、自分の参照を変更しますが、オブジェクトを共有プールに入れます。それが中に呼び出されたレポがすべて参照の知識を持っていない限り、最も重要なのgitガベージコレクタは呼び出されない必要があります - - だけでなく、いくつかのより多くのものが世話をしなければならない、本当に使えるようにするもちろん
それは自分のものです。さもなければ、それは参照から到達可能ではないが他のreposの参照から到達可能な共有プール内のオブジェクトを破棄することができます。
githubはフォークの作成中にハードリンクのような何らかの最適化を使用する可能性がありますが、すべての実用的な目的でgithubサーバー自体の単なるクローンです。 –
@ NoufalIbrahim:はい。フォークがファイルのリビジョンを実際にコミットするまでディスクスペースを節約するために内部最適化を行うように努力することは間違いありません。しかし、それは実際にユーザーには透過的です。しかし、良い点。 – jdi
@ NoufalIbrahim:私たちが知っているように、上流のレポが新しいコミットを受け取ったとき、フォークには何の影響も与えないので、それはもっと複雑だと思います。それらは個別に下流のフェッチを担当します。 – jdi