web-dev-qa-db-ja.com

Gitはシンボリックリンクをどのように処理しますか?

シンボリックリンクのファイルまたはディレクトリがあり、それをGitリポジトリにコミットした場合、どうなりますか?

私はそれがファイルが削除されるまでそれがシンボリックリンクとしてそれを残すと思います、そしてあなたが古いバージョンからファイルを引き戻すならばそれはただ普通のファイルを作成します。

参照しているファイルを削除するとどうなりますか。ダングリングリンクをコミットするだけですか?

1436
Alex

Gitは通常のファイルと同じようにリンクの内容(リンク先のファイルシステムオブジェクトのパス)を 'blob'に格納するだけです。次に、名前、モード、およびタイプ(それがシンボリックリンクであることを含む)を、それを含むディレクトリを表すツリーオブジェクトに格納します。

リンクを含むツリーをチェックアウトすると、ターゲットファイルシステムオブジェクトが存在するかどうかに関係なく、オブジェクトはシンボリックリンクとして復元されます。

シンボリックリンクが参照しているファイルを削除しても、Gitが制御するシンボリックリンクにはまったく影響しません。ぶら下がっている参照があります。必要に応じて有効なリンクを指すようにリンクを削除または変更するのはユーザーの責任です。

1199
CB Bailey

TL; DR:シンボリックリンクによって参照されるデータはリポジトリに保存されません。


ファイルをインデックスに追加したときにGitが何をするのかを見ることで、Gitがそのファイルに対して何をするのかを知ることができます。インデックスはプリコミットのようなものです。インデックスをコミットしたら、git checkoutを使用して、インデックスに含まれていたものすべてを作業ディレクトリに戻すことができます。それで、インデックスにシンボリックリンクを追加すると、Gitは何をするのでしょうか。

調べるには、まずシンボリックリンクを作成します。

$ ln -s /path/referenced/by/symlink symlink

Gitはこのファイルについてまだ知りません。 git ls-filesはあなたのインデックスを調べることを可能にします(-sstat-like出力をプリントします):

$ git ls-files -s ./symlink
[nothing]

それでは、シンボリックリンクの内容をインデックスに追加して、Gitオブジェクトストアに追加します。ファイルをインデックスに追加すると、Gitはその内容をGitオブジェクトストアに格納します。

$ git add ./symlink

それで、何が追加されましたか?

$ git ls-files -s ./symlink
120000 1596f9db1b9610f238b78dd168ae33faa2dec15c 0       symlink

ハッシュは、Gitオブジェクトストアに作成されたパックオブジェクトへの参照です。リポジトリのルートにある.git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15cを見ると、このオブジェクトを調べることができます。 このファイルはGitが保存するもので、シンボリックリンクを追加してコミットしたときにリポジトリからチェックアウトできるものです。 このファイルを調べると、非常に小さいことがわかります。リンクファイルの内容は保存されません。

(注120000ls-filesの出力にリストされているモードです。通常のファイルの場合は100644のようになります。)

しかし、Gitがリポジトリからファイルシステムにチェックアウトしたときに、このオブジェクトに対して何をするのでしょうか。それはcore.symlinks設定に依存します。 man git-config から:

core.symlinks

Falseの場合、シンボリックリンクはリンクテキストを含む小さなプレーンファイルとしてチェックアウトされます。

そのため、リポジトリのシンボリックリンクを使用すると、チェックアウト時に、core.symlinks設定の値に応じて、ファイルシステムのフルパスへの参照を含むテキストファイル、または適切なシンボリックリンクを取得できます。

どちらの方法でも、シンボリックリンクによって参照されるデータはリポジトリに格納されません。

197

"編集者用"注:この投稿には古い情報が含まれている可能性があります。コメントおよび この質問 1.6.1以降のGitの変更についてをご覧ください。

シンボリックディレクトリ:

ソフトリンクのディレクトリがあるとどうなるかに注意することが重要です。更新を伴うGit pullはリンクを削除して通常のディレクトリにします。これが私が苦労して学んだことです。いくつかの洞察 ここ / ここ。

 ls -l
 lrwxrwxrwx 1 admin adm   29 Sep 30 15:28 src/somedir -> /mnt/somedir

git add/commit/Push

It remains the same

git pullおよびいくつかの更新が見つかった後

 drwxrwsr-x 2 admin adm 4096 Oct  2 05:54 src/somedir
144
Shekhar