4

If you want to clone a git repository with submodules for use exclusively within Cygwin, you can. Take pymode, a Vim plugin, as an example. You can, from within Cygwin, perform git clone described in their documentation without issue.

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

From there, you can start using the Cygwin version of Vim to enjoy the plugin without issue.

But if you wanted to clone the repository for use with a Windows-only, no-cygwin program - such as the Windows version of Vim - then you will run into an incompatibility between Cygwin-style symlinks and native Windows programs. In short - they're not compatible. Native Windows applications don't know how to handle the Cygwin symlinks. But they shouldn't be expected to!

Fortunately, Cygwin has the ability to use Windows native symlinks on the versions of Windows that support it. (Vista and higher) All you have to do is, from within your Administrator-privileged Cygwin session, export CYGWIN=winsymlinks:nativestrict. This will force Cygwin to use native Windows symlinks. (If it can't, for whatever reason, then the attempt to create the link will fail.)

In addition to telling Cygwin to create symlinks, you will also have to tell git to create symlinks with -c core.symlinks=true, replacing the git clone line above with the following:

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

So far so good. So you run your clone... and it fails!

$ 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'

Why does it do that?

1 Answer 1

2

If you look closely at the failure, you can see that the problem was in creating the symlinks to the submodules. Strangely, the error says "No such file or directory". This is odd because creating symlinks to non-existent targets is supported by both the Linux and Windows versions of symlinks.

However, Cygwin doesn't allow this behavior. Assuming that the directory C:\notreallythere does not exist, creating a link to it fails:

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

Furthermore, this is not likely to be fixed. It has been pointed out before and remains a problem at time of writing.
https://sourceware.org/ml/cygwin/2016-04/msg00658.html
https://sourceware.org/ml/cygwin/2018-09/msg00115.html

So how does this prevent the recursive git clone? When git clones a repository with submodules, it creates symlinks to the modules before it clones them. Normally, this is fine because you can ordinarily have dangling symlinks and populate them later. But not in Cygwin!

So if you want to clone a git repository with submodules for use within Windows, you'll have to use something other than Cygwin's git.

EDIT: AFAICT, this is because Windows are not agnostic as to whether the target is a file or a directory, while POSIX symlinks are.

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .