シンボリックリンクをコピーに置き換えるシェルスクリプトを使用するのが最善ですか、それともGitにシンボリックリンクをたどるように指示する別の方法がありますか?
PS:あまり安全ではないことは知っていますが、特定の場合にのみ実行したいと思います。
シンボリックリンク内のファイルをGitに取得するために追加したこと(シンボリックリンクは使用しませんでしたが):
sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY
このコマンドは、Git が管理するディレクトリで実行します。をマウントするTARGETDIRECTORY
前に作成する必要があります。SOURCEDIRECTORY
Linux では正常に動作しますが、OS X では動作しません! そのトリックは、Subversion でも役に立ちました。私はこれを使用して、ウェブ デザイナーが作業を行う Dropbox アカウントのファイルを含めます。
このバインドを永続的にしたい場合は、次の行を に追加します/etc/fstab
。
/sourcedir /targetdir none bind
逆にシンボリックリンクを作成してみませんか?つまり、Gitリポジトリからアプリケーションディレクトリにリンクするのではなく、その逆にリンクするだけです。
たとえば~/application
、構成ファイルを必要とするにインストールされているアプリケーションをセットアップしているとしましょうconfig.conf
。
config.conf
たとえば、Gitリポジトリに追加します~/repos/application/config.conf
。~/application
次に、を実行して からシンボリックリンクを作成しますln -s ~/repos/application/config.conf
。このアプローチは常に機能するとは限りませんが、これまでのところうまく機能しました。
注: Git 1.6.1 以降、このアドバイスはコメントごとに古くなっています。Git は以前はこのように動作していましたが、現在はそうではありません。
デフォルトでは、Git はシンボリック リンクをたどる代わりに保存しようとします (コンパクトにするためであり、一般的に人々が望んでいることです)。
ただし、シンボリックリンクがディレクトリの場合、シンボリックリンクを超えてファイルを追加することができました。
すなわち:
/foo/
/foo/baz
/bar/foo --> /foo
/bar/foo/baz
することによって
git add /bar/foo/baz
私が試したところ、うまくいくように見えました。ただし、その動作は当時の私には望ましくなかったので、それ以上の情報を提供することはできません.
これは、インデックス内のシンボリック リンク blob をそれらのシンボリック リンクのコンテンツに置き換えるpre-commit フックです。
これを に入れ、.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 に準拠していない可能性があります。
このコードはある程度テストされていますが、間違い/エラーがある可能性があります。
macOS (私は Mojave/ 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>
他のコメントで示唆されていますが、他の回答では明確に提供されていません。うまくいけば、これで誰かの時間を節約できます。
私はかなり長い間、シンボリックリンクを超えてファイルを追加していました。これは、特別な調整をしなくても問題なく機能していました。Git 1.6.1 にアップデートしてから、これが機能しなくなりました。
これを機能させるには、Git 1.6.0 に切り替えることができる場合があります。Git の将来のバージョンで、git-add
再びシンボリック リンクをたどることができるようにフラグが設定されることを願っています。
Git 2.3.2+ (2015 年第 1 四半期) では、Git がシンボリック リンクをたどらない別のケースが 1 つあります。 Junio C Hamanoによるコミット e0d201bを参照してください ( ) (メインの Git メンテナー)gitster
apply
: シンボリック リンクを超えてファイルに触れないでくださいGit はシンボリック リンクをシンボリック リンクとして追跡するため、先頭部分にシンボリック リンクを含むパス (たとえば
path/to/dir/file
、 wherepath/to/dir
は作業ツリーの内部または外部のどこかへのシンボリック リンク) は、有効に適用されるパッチに表示されることはありません。 、同じパッチが最初にシンボリックリンクを削除して、そこにディレクトリを作成できるようにしない限り。そのようなパッチを検出して拒否します。
同様に、input がシンボリック リンク
path/to/dir
を作成してから file を作成する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
Darwin では動作しないようです。
誰かがそうするトリックを持っていますか?
[編集]
OK、Mac OS X での答えはハードリンクを作成することであることがわかりました。ただし、その API は を介して公開されていないln
ため、これを行うには独自の小さなプログラムを使用する必要があります。そのプログラムへのリンクは次のとおりです。
楽しみ!
シンボリックリンクからの変換が役立つ場合があります。スクリプトによるシンボリック リンクの代わりに、Git フォルダーにリンクします。
私は Git 1.5.4.3 を使用していますが、末尾にスラッシュがある場合は、渡されたシンボリック リンクをたどっています。例えば
# Adds the symlink itself
$ git add symlink
# Follows symlink and adds the denoted directory's contents
$ git add symlink/