web-dev-qa-db-ja.com

Windowsネイティブシンボリックリンクを使用してCygwinのサブモジュールでgitリポジトリのクローンを作成できないのはなぜですか?

Cygwin内で排他的に使用するためにサブモジュールを使用してgitリポジトリのクローンを作成する場合は、それが可能です。例として、Vimプラグインである pymode を取り上げます。 Cygwin内から、ドキュメントに記載されているgitcloneを問題なく実行できます。

cd ~/.vim/pack/python-mode/start
git clone --recurse-submodules https://github.com/python-mode/python-mode.git
cd python-mode

そこから、CygwinバージョンのVimを使い始めて、問題なくプラグインを楽しむことができます。

ただし、Windows専用のcygwinを使用しないプログラム(WindowsバージョンのVimなど)で使用するためにリポジトリのクローンを作成する場合は、CygwinスタイルのシンボリックリンクとネイティブのWindowsプログラムの間に非互換性が発生します。つまり、互換性はありません。ネイティブWindowsアプリケーションは、Cygwinシンボリックリンクを処理する方法を知りません。しかし、彼らは期待されるべきではありません!

幸い、Cygwinには、それをサポートするバージョンのWindowsでWindowsネイティブシンボリックリンクを使用する機能があります。 (Vista以降)あなたがしなければならないのは、管理者特権のCygwinセッション内からexport CYGWIN=winsymlinks:nativestrictだけです。これにより、CygwinはネイティブのWindowsシンボリックリンクを使用するようになります。 (何らかの理由でそれができない場合、リンクを作成する試みは失敗します。)

Cygwinにシンボリックリンクを作成するように指示することに加えて、-c core.symlinks=trueでシンボリックリンクを作成するようにgitに指示し、上記のgitクローン行を次のように置き換える必要があります。

git clone --recurse-submodules https://github.com/python-mode/python-mode -c core.symlinks=true

ここまでは順調ですね。だからあなたはあなたのクローンを実行します...そしてそれは失敗します!

$ git clone --recurse-submodules https://github.com/python-mode/python-mode.git -c core.symlinks=true
Cloning into 'python-mode'...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 8044 (delta 14), reused 32 (delta 12), pack-reused 8002
Receiving objects: 100% (8044/8044), 10.67 MiB | 3.39 MiB/s, done.
Resolving deltas: 100% (3234/3234), done.
error: unable to create symlink pymode/autopep8.py: No such file or directory
error: unable to create symlink pymode/libs/astroid: No such file or directory
error: unable to create symlink pymode/libs/logilab: No such file or directory
error: unable to create symlink pymode/libs/mccabe.py: No such file or directory
error: unable to create symlink pymode/libs/pycodestyle.py: No such file or directory
error: unable to create symlink pymode/libs/pydocstyle: No such file or directory
error: unable to create symlink pymode/libs/pyflakes: No such file or directory
error: unable to create symlink pymode/libs/pylama: No such file or directory
error: unable to create symlink pymode/libs/pylint: No such file or directory
error: unable to create symlink pymode/libs/rope: No such file or directory
error: unable to create symlink pymode/libs/six.py: No such file or directory
error: unable to create symlink pymode/libs/snowballstemmer: No such file or directory
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry the checkout with 'git checkout -f HEAD'

なぜそれをするのですか?

3
EchoLynx

失敗をよく見ると、問題はサブモジュールへのシンボリックリンクの作成にあったことがわかります。不思議なことに、エラーには「そのようなファイルやディレクトリはありません」と表示されます。存在しないターゲットへのシンボリックリンクの作成は、 Linux バージョンと Windows バージョンの両方のシンボリックリンクでサポートされているため、これは奇妙なことです。

ただし、Cygwin この動作は許可されていません 。ディレクトリC:\ notreallythereが存在しないと仮定すると、そのディレクトリへのリンクの作成は失敗します。

$ ln -sf /cygdrive/c/notreallythere
ln: failed to create symbolic link './notreallythere': No such file or directory

さらに、これは修正される可能性が低いです。これは以前に指摘されており、執筆時点では問題が残っています。
https://sourceware.org/ml/cygwin/2016-04/msg00658.html
https://sourceware.org/ml/cygwin/2018-09/msg00115.html

では、これはどのようにして再帰的なgitクローンを防ぐのでしょうか? gitがサブモジュールを含むリポジトリのクローンを作成する場合、モジュールのクローンを作成する前にモジュールへのシンボリックリンクを作成します。通常、これは問題ありません。通常、ぶら下がっているシンボリックリンクを作成して、後で入力できるからです。しかし、Cygwinではありません!

したがって、Windows内で使用するサブモジュールを使用してgitリポジトリのクローンを作成する場合は、Cygwinのgit以外のものを使用する必要があります。

編集:AFAICT、これは、Windowsがターゲットがファイルであるかディレクトリであるかを認識しないのに対し、POSIXシンボリックリンクは認識しているためです。

C:\>mklink /?
Creates a symbolic link.

MKLINK [[/D] | [/H] | [/J]] Link Target

        /D      Creates a directory symbolic link.  Default is a file
                symbolic link.
        /H      Creates a hard link instead of a symbolic link.
        /J      Creates a Directory Junction.
        Link    Specifies the new symbolic link name.
        Target  Specifies the path (relative or absolute) that the new link
                refers to.
2
EchoLynx