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
done
What 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