私のベストは、シンボリックリンクをコピーで置き換えるシェルスクリプトになるでしょうか、それともシンボリックリンクをたどるようにGitに指示する別の方法がありますか?
PS:それほど安全ではないことはわかっていますが、特定の状況でのみ実行したいと思っています。
私のベストは、シンボリックリンクをコピーで置き換えるシェルスクリプトになるでしょうか、それともシンボリックリンクをたどるようにGitに指示する別の方法がありますか?
PS:それほど安全ではないことはわかっていますが、特定の状況でのみ実行したいと思っています。
回答:
注:このアドバイスは、Git 1.6.1以降、コメントに従って古くなっています。Gitは以前はこのように動作し、現在は動作していません。
デフォルトでは、Gitはシンボリックリンクをたどるのではなく保存することを試みます(コンパクトにするために、そしてそれは一般的に人々が望んでいることです)。
しかし、シンボリックリンクがディレクトリの場合、誤ってシンボリックリンクを超えてファイルを追加することができました。
すなわち:
/foo/
/foo/baz
/bar/foo --> /foo
/bar/foo/baz
することによって
git add /bar/foo/baz
私がそれを試したときそれは動作するように見えました。しかし、その行動は当時私には望ましくなかったので、それ以上の情報を提供することはできません。
シンボリックリンク内のファイルをGitに取得するために追加したこと(シンボリックリンクは使用しませんでした):
sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY
このコマンドは、Git管理のディレクトリで実行してください。TARGETDIRECTORY
をSOURCEDIRECTORY
マウントする前に作成する必要があります。
Linuxでは正常に機能しますが、OS Xでは機能しません。そのトリックは、Subversionにも役立ちました。Dropboxアカウントのファイルを含めるために使用しています。ウェブデザイナーが自分の作業を行っています。
umount [mydir]
。(あなたの素晴らしいヒントのために+ 1、@ user252400)
逆にシンボリックリンクを作成してみませんか?Gitリポジトリからアプリケーションディレクトリにリンクする代わりに、逆にリンクするだけです。
たとえば~/application
、構成ファイルを必要とするアプリケーションがインストールされているとしますconfig.conf
。
config.conf
たとえば、Gitリポジトリに追加します~/repos/application/config.conf
。~/application
を実行して からシンボリックリンクを作成しますln -s ~/repos/application/config.conf
。このアプローチは常に機能するとは限りませんが、今のところ私にはうまくいきました。
代わりにハードリンクを使用してください。これは、ソフト(シンボリック)リンクとは異なります。を含むすべてのプログラムはgit
、ファイルを通常のファイルとして扱います。内容は変更することによって修正することができることに留意されたいのいずれかのソースまたは宛先を。
gitとXcodeがすでにインストールされている場合は、hardlinkをインストールします。ハードリンクを作成するための微視的なツールです。
ハードリンクを作成するには、単純に:
hln source destination
Apple File Systemはディレクトリのハードリンクをサポートしていますか?
ディレクトリのハードリンクは、Appleファイルシステムではサポートされていません。macOSでHFS +からAPFSボリューム形式に変換すると、すべてのディレクトリハードリンクがシンボリックリンクまたはエイリアスに変換されます。
今後の代替案については、https://github.com/selkhateeb/hardlink/issues/31をフォローしてください。
ln
コマンドは、ハードリンクを作ることができます。
ln source destination
誰かがmklinkを使用してWindowsでジャンクションを作成することを提案しましたが、私は試していません。
mklink /j "source" "destination"
ln source destination
OS Xでも動作します。El Capitanでテスト済み。
cp -al source destination
。`-l 'はファイルのコピーではなくハードリンクを意味します。
これは、インデックス内のシンボリックリンクblobをこれらのシンボリックリンクのコンテンツで置き換える事前コミットフックです。
これをに入れ.git/hooks/pre-commit
、実行可能にします。
#!/bin/sh
# (replace "find ." with "find ./<path>" below, to work with only specific paths)
# (these lines are really all one line, on multiple lines for clarity)
# ...find symlinks which do not dereference to directories...
find . -type l -exec test '!' -d {} ';' -print -exec sh -c \
# ...remove the symlink blob, and add the content diff, to the index/cache
'git rm --cached "$1"; diff -au /dev/null "$1" | git apply --cached -p1 -' \
# ...and call out to "sh".
"process_links_to_nondir" {} ';'
# the end
可能な限りPOSIX準拠の機能を使用しています。ただし、diff -a
おそらくPOSIXに準拠していません。
多少テストされていますが、このコードにはいくつかの間違い/エラーがあるかもしれません。
typechange
されることに注意してくださいgit status
。
process_links_to_nondir
?
argv[0]
コマンド名として使用されるのはname / sh
です。(それが何であるかを覚えていなかったので、それを理解するために少し私を調べましたeither)
find: missing argument to -exec'
ます。すべてを単一行にパイプ&結合するのではなく、ステップごとのコマンド実行が必要になる場合があります。
typechange
@DavidFraser のように表示されますが、リンクされたファイルはもうステージングされていないようです)
オンMacOS
(Iはモハーベ/ 10.14、持っているgit
、使用バージョン2.7.1)をbindfs
。
brew install bindfs
cd /path/to/git_controlled_dir
mkdir local_copy_dir
bindfs </full/path/to/source_dir> </full/path/to/local_copy_dir>
他のコメントが示唆されていますが、他の回答では明確に提供されていません。うまくいけば、これは誰かの時間を節約できます。
Failed to resolve
... No such file or directory
エラーが発生することに注意してください。bindfs
私はかなり長い間、symlinksを超えてファイルを追加していた。これは、特別な調整を行うことなく、以前はうまく機能していました。Git 1.6.1にアップデートしてから、これは機能しなくなりました。
これを動作させるためにGit 1.6.0に切り替えることができる場合があります。将来のバージョンのGitには、git-add
シンボリックリンクを再びたどることができるフラグが付けられることを期待しています。
ここにあるすべてのソリューションが古くなっている、またはルートが必要なことに飽きてきたので、LD_PRELOADベースのソリューションを作成しました(Linuxのみ)。
これはGitの内部にフックし、「これはシンボリックリンクですか?」をオーバーライドします。関数。シンボリックリンクをそのコンテンツとして扱うことができます。デフォルトでは、リポジトリ外へのリンクはすべてインライン化されます。詳細については、リンクを参照してください。
LD_PRELOAD
ライブラリ関数をオーバーライドするために使用する非常に創造的なソリューション!
Gitの2.3.2+(Q1 2015年)では、Gitはなり一つの他のケースがありませんもはやシンボリックリンクをたどるには:参照e0d201bコミットによってJunio C浜野(gitster
)(メインGitのメンテナ)
apply
:シンボリックリンクを越えてファイルに触れないでくださいGitはシンボリックリンクをシンボリックリンクとして追跡するため、先頭部分にシンボリックリンクがあるパス(たとえば
path/to/dir/file
、path/to/dir
はどこかへのシンボリックリンクで、作業ツリーの内部または外部にある)は、有効に適用されるパッチに表示できません。 、同じパッチが最初にシンボリックリンクを削除して、そこにディレクトリを作成できるようにする場合を除きます。このようなパッチを検出して拒否します。
同様に、入力がシンボリックリンク
path/to/dir
を作成してからファイルを作成するpath/to/dir/file
場合path/to/dir
、ファイルシステムに実際にシンボリックリンクを作成せずに、エラーとしてフラグを立てる必要があります。代わりに、結果にパス(つまり、削除されない)が残っている入力内のすべてのパッチについて、入力内のすべてのパッチを検査し、次にパッチのターゲットを検査することにより、パッチが作成する結果のツリーに対してすべての先行パスをチェックしますアプリケーション(インデックスまたは作業ツリー)。
このように、我々は:
- いたずらや間違いを見つけて、シンボリックリンク
path/to/dir
とファイルpath/to/dir/file
を同時に追加する、- シンボリックを削除し
link path/to/dir
てからファイルを追加する有効なパッチを許可するpath/to/dir/file
。
つまり、その場合、エラーメッセージはのような一般的なもの"%s: patch does not apply"
ではなく、より具体的なものになります。
affected file '%s' is beyond a symbolic link
うーん、mount --bind
ダーウィンでは動作しないようです。
誰かがそれをするトリックを持っていますか?
[編集]
OK、Mac OS Xでの答えはハードリンクを作ることだとわかりました。ただし、そのAPIはを介して公開されないln
ため、独自の小さなプログラムを使用してこれを行う必要があります。ここにそのプログラムへのリンクがあります:
楽しい!
私はGit 1.5.4.3を使用していますが、末尾にスラッシュがある場合、渡されたシンボリックリンクをたどっています。例えば
# Adds the symlink itself
$ git add symlink
# Follows symlink and adds the denoted directory's contents
$ git add symlink/
fatal: 'src/' is beyond a symbolic link