Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Make ln create Windows symlinks #4

Closed
wants to merge 1 commit into from

5 participants

@svnpenn
Collaborator

This was discussed a while back here

Currently when I build git on Windows, all ln -s does is make a copy of the file.

This script is one way to actually make the symlinks in libexec/git-core.

You can put it right alongside ln.exe and it will be used first.

@dscho
Owner

Okay, so there are a few problems with this (which is the reason why I will not merge right away):

  • the commit message is a bit, uhm, terse :-) (IOW just put all the stuff you put in the pull request into the commit message, preferably with salient quotes from the discussion on our mailing list), and

  • mklink is not available everywhere, right? We need to make an effort to stay compatible with XP (if you ask me, that was the best Windows version anyway), and

  • as far as I remember, NTFS junctions are not quite the same as symlinks. So probably we want to test for the corner cases (IIRC there were issues with linking directories?) and print helpful messages, and

  • (minor nit) I do not have anything against including those links even if I think they will become stale faster than butter in the sun, but I'd like to have full URLs, i.e. with http:// prefixes.

Thanks!
Johannes

@sschuberth
Owner

Some misc. comments from my side as I feel some terms are mixed up here:

  • There are three types of file system links on Windows: hardlinks, junctions, and symlinks. Hardlinks and junctions are available since NT. Hardlinks can only point to files, junctions only to directories (on the same volume). The symlinks available since Vista can point to either files or directories, also on different volumes.

  • mklink, which ships since Vista, can create all of the above. But the way it is called in the script makes it only create symlinks (which is good, IMHO, as they most closely resemble Linux symbolic links).

  • For pre-Vista, we'd need a fallback that either creates hardlinks for files using "fsutil hardlink" (but probably only if "ln" is called without "-s") and creates junctions for directories using "fsutils reparsepoint", or simply calls the original ln.exe.

@kusma
Owner

In addition to breaking Windows XP setups, a change like this will also break standard Windows 7 setups, because mklink requires administrator privileges by default. This can be fixed by checking if it worked or not, and reverting to copying in such cases.

Just for the record: I played around a bit with trying to make symlink support in Git for Windows itself recently, but ended up concluding that the "symlink support" in Windows 7 and up is pretty close to useless for emulating Unix symlinks.

@svnpenn
Collaborator

I appreciate all the feedback. I think the best fallback for XP would be to simply use ln.exe, but I'm not sure how I would make that work.

@dscho
Owner

Has the fallback been implemented yet?

@svnpenn
Collaborator

I have no interest in making a fallback. My posted solution work for me, although it is slower than ln.exe.

@dscho
Owner

Oh, okay. So this pull request can be closed?

@svnpenn
Collaborator

Sure thing, thank you sir.

@dscho dscho closed this
@svnpenn
Collaborator

Hey! Look at this!

Open Source, 100% Compatible ln for Windows

Do it please.

@dscho
Owner

Thanks for the link! But if you have no interest in working on this, what interest should I then have? ;-)

@svnpenn
Collaborator

Well hey, they already did it for us :)

@kusma
Owner

Unfortunately, normal users doesn't have the required permissions to create symlinks by default on Windows. Combine this with the fact that you cannot change what a symlink points to in the same way that POSIX requires, makes them more or less useless for us. This I already wrote above.

Now, the authors can claim all they want that this is "100% compatible" for all I care, but a quick look at the source code reveals that it's not. They do not provide any fallbacks, they don't even load the CreateSymbolicLink function dynamically. So the result on non-symlink capable Windows versions will be a crash with a missing symbol error.

@sschuberth
Owner

For reference, here's another link to a utility called winln (I'm not suggesting to use it, though, as I've not tried it).

@dscho
Owner

The latest experiences regarding symbolic links are not happy ones. It seems they fail to accomplish the job at least in conjunction with CopSSH. (I'd have appreciated more in-depth research regarding the issue from the OP.)

@ariofrio

Currently, what happens when I clone a repository with symlinks in Windows?

@svnpenn
Collaborator

@ariofrio you are off topic. The discussion is about the output from building git from source.

@ariofrio

@svnpenn: I thought it was about adding a feature to msysgit. But never mind, I've started a question on SO.

@charleso charleso referenced this pull request in charleso/git-cc
Closed

Soft links not copied #6

@dscho dscho referenced this pull request in msysgit/git
Closed

Windows 7, Invalid symlink #83

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 23, 2012
  1. @svnpenn

    ln

    svnpenn authored
This page is out of date. Refresh to see the latest.
Showing with 26 additions and 0 deletions.
  1. +26 −0 bin/ln
View
26 bin/ln
@@ -0,0 +1,26 @@
+#!/bin/sh
+# github.com/dansmith65/git/blob/master/contrib/workdir/git-new-workdir-win
+# stackoverflow.com/questions/8409024
+#
+# TESTS
+# ln "/c/a/git.exe" "/c/a/git-add.exe"
+# ln -s "/c/a/b" "/c/a/b-link"
+# ln -s "/c/a/git git.exe" "/c/a/git git-add.exe"
+# ln -s "/c/a/git.exe" "$HOME/git-add.exe"
+# ln -s "/c/a/git.exe" "/c/a/git-add.exe"
+# ln -s "C:\a\git.exe" "C:\a\git-add.exe"
+
+for i in 0 1
+do
+ arg="${BASH_ARGV[$i]}"
+ dn=$(cd "$(dirname "$arg")"; pwd -W)
+ bn=$(basename "$arg")
+ paths+="\"$dn/$bn\" "
+done
+
+if test -d "$2"
+ then is_dir='/d'
+fi
+
+# ".exe" is required
+cmd.exe /c "mklink $is_dir $paths"
Something went wrong with that request. Please try again.