msysgit & corrupted symbolic links
Using msysgit on Windows?
Let's say the project you are cloning has:
real-directory-1/Where linked-directory-1/ is a symbolic link to real-directory-1/.
real-directory-2/linked-directory-1/
What you will find in your clone of this project is:
real-directory-1/Where linked-directory-1 is a file containing the local path of what it's target would be if it were the symbolic link it were supposed to be.
real-directory-2/linked-directory-1
The problem?
Cloning projects in a broken state just seemed.. ridiculously unusable. I've wasted hours on errors that appear to be in one place, but are actually because of these broken symbolic links. With a bit of googling, I encountered someone suggesting that someone else set their core.symlink GIT setting. Out of curiosity, I decided to check the .git/config file in my cloned project.
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
I don't understand.. The default value is to create broken clones, with missing symlinks and junk files littered throughout them? Is there something I am missing here?
The solution?
A bit of further searching revealed that you can set this setting globally. Something like:
git config --global core.symlink trueAfter executing that, and then modifying the red highlighted project-specific setting..
$ git checkout -fNow the files are missing, but at least I know that the clone is bad.
error: unable to create symlink AndroidAppSettings.cfg (Function not implemented)
error: unable to create symlink project/jni/application/atari800/atari800 (Function not implemented)
I think the best approach is to have it work this way by default, then cloned projects can have their local setting changed in their configuration file. Then the corrupted clone can be processed with a script to turn the corrupt files into the links they should be.
The following almost does the trick:
#!/bin/sh git ls-files -s | awk '/120000/{print $4}' | while read FILEPATH do if [ ! -e $FILEPATH ]; then echo "Please check that GIT core.symlink for this project is 'false'" 1>2 exit 1 fi if [ ! -L $FILEPATH ] && [ -f $FILEPATH ]; then wc -l $FILEPATH | while read LINES DISCARD do if [ "$LINES" = "0" ]; then FILEDIR=`dirname $FILEPATH` FILENAME=`basename $FILEPATH` LINKPATH=`cat $FILEPATH` pushd . > /dev/null cd $FILEDIR if [ -e $FILENAME ]; then if [ -e $LINKPATH ]; then ln -s -f $LINKPATH $FILENAME echo "Repairing symlink: $FILEPATH" else echo "$FILEPATH: symlink path '$LINKPATH' invalid" 1>2 fi else echo "$FILEPATH: problem finding this file" fi popd > /dev/null else # ERROR: Expected a file with one line for the link path echo "$FILEPATH: bad link file: expected 0 lines, got $LINES" > /dev/null # 1>2 fi done else echo "$FILEPATH: already a symlink" > /dev/null # 1>2 fi doneWhat it does not do, is create a symbolic link within the same directory, to that same directory the link is intended to reside within.
Conclusion
Do not use Git for Windows AKA msysgit. Even if you work around the corrupted files with the above script, you cannot make the links yourself because some cases are not supported by the ln command. You can get a little further by switching over to a MinGW msys installation (the above script works in the "does not do" case), but there are still problems. It is probable that MinGW ln is copying, rather than linking, given the time the script takes to run.
Cygwin has the same problem, when using it's git command.
Portable Ubuntu has been recommended, but I haven't tried it yet, or looked at it's suitability.
Next: Android NDK & Windows symbolic links.
No comments:
Post a Comment