我们的开发人员混合使用Windows和基于unix的操作系统。因此,在Unix机器上创建的符号链接成为Windows开发人员的一个问题。在Windows (MSysGit)中,符号链接被转换为一个文本文件,并带有它所指向的文件的路径。相反,我想将符号链接转换为实际的Windows符号链接。

我对此的(更新的)解决方案是:

编写一个检出后脚本,递归地查找“符号链接”文本文件。 将它们替换为Windows符号链接(使用mklink),具有与虚拟“symbolic link”相同的名称和扩展名 通过在文件.git/info/exclude中添加一个条目来忽略这些Windows符号链接

我还没有实现这个方法,但我相信这是解决这个问题的可靠方法。

如果有的话,你认为这种方法有什么缺点? 这个后签出脚本是可实现的吗?也就是说,我能递归地找到Git创建的虚拟“符号链接”文件吗?


当前回答

对于那些在Windows Vista、Windows 7或更高版本上使用Cygwin的人来说,原生git命令可以创建“适当的”符号链接,这些符号链接可以被Windows应用程序(如Android Studio)识别。你只需要设置CYGWIN环境变量来包含winsymlinks:native或winsymlinks:nativestrict,就像这样:

export CYGWIN="$CYGWIN winsymlinks:native"

这样做的缺点(也是一个很重要的缺点)是Cygwin shell必须是“以管理员身份运行”,这样它才能拥有创建这些符号链接所需的操作系统权限。但是,一旦创建了它们,就不需要特殊的权限来使用它们。只要它们没有在存储库中被另一个开发人员更改,git就可以在正常的用户权限下正常运行。

就我个人而言,我只对Windows应用程序(即非cygwin)导航的符号链接使用这种方法,因为这增加了难度。

有关此选项的更多信息,请参阅堆栈溢出问题:如何在Windows 7中使用Cygwin创建符号链接

其他回答

下面是一个批处理脚本,用于转换存储库中的符号链接,仅用于文件,基于Josh Lee的回答。https://gist.github.com/Quazistax/8daf09080bf54b4c7641上有一个带有管理员权限检查功能的脚本。

@echo off
pushd "%~dp0"
setlocal EnableDelayedExpansion

for /f "tokens=3,*" %%e in ('git ls-files -s ^| findstr /R /C:"^120000"') do (
     call :processFirstLine %%f
)
REM pause
goto :eof

:processFirstLine
@echo.
@echo FILE:    %1

dir "%~f1" | find "<SYMLINK>" >NUL && (
  @echo FILE already is a symlink
  goto :eof
)

for /f "usebackq tokens=*" %%l in ("%~f1") do (
  @echo LINK TO: %%l

  del "%~f1"
  if not !ERRORLEVEL! == 0 (
    @echo FAILED: del
    goto :eof
  )

  setlocal
  call :expandRelative linkto "%1" "%%l"
  mklink "%~f1" "!linkto!"
  endlocal
  if not !ERRORLEVEL! == 0 (
    @echo FAILED: mklink
    @echo reverting deletion...
    git checkout -- "%~f1"
    goto :eof
  )

  git update-index --assume-unchanged "%1"
  if not !ERRORLEVEL! == 0 (
    @echo FAILED: git update-index --assume-unchanged
    goto :eof
  )
  @echo SUCCESS
  goto :eof
)
goto :eof

:: param1 = result variable
:: param2 = reference path from which relative will be resolved
:: param3 = relative path
:expandRelative
  pushd .
  cd "%~dp2"
  set %1=%~f3
  popd
goto :eof

我建议您不要在存储库中使用符号链接。将实际内容存储在存储库中,然后在存储库外放置指向内容的符号链接。

因此,假设您正在使用一个存储库来比较在类unix系统上托管站点与在Windows上托管站点。将内容存储在您的存储库中,例如/httpRepoContent和c:\httpRepoContent,这是通过Git、SVN等同步的文件夹。

然后,替换你的web服务器的内容文件夹(/var/www和c:\程序文件\web server\www{名称并不重要,如果你必须编辑}),用一个符号链接到你的存储库中的内容。web服务器将看到内容实际上是在“正确”的位置,但你可以使用你的源代码控制。

但是,如果您需要在存储库中使用符号链接,您将需要研究一些类似于前/后提交脚本的东西。我知道您可以使用它们来做一些事情,例如通过格式化程序解析代码文件,因此应该可以在平台之间转换符号链接。

如果有人知道一个好地方可以学习如何为常见的源代码控制、SVN、Git和MG执行这些脚本,那么请添加评论。

我一直在寻找一种简单的解决方案来处理Windows上的Unix符号链接。非常感谢您在之前的回答中提供Git别名。

可以对rm-符号链接进行一个小小的优化,以便在别名意外第二次运行时它不会删除目标文件夹中的文件。请观察循环中的新if条件,以确保在逻辑运行之前文件不是到目录的链接。

git config --global alias.rm-symlinks '!__git_rm_symlinks(){
for symlink in $(git ls-files -s | egrep "^120000" | cut -f2); do
    *if [ -d "$symlink" ]; then
      continue
    fi*
    git rm-symlink "$symlink"
    git update-index --assume-unchanged "$symlink"
done
}; __git_rm_symlinksenter

Git SCM的最新版本(在版本2.11.1上测试)允许启用符号链接。但是你必须再次用符号链接克隆存储库git clone -c core。符号链接= true > < URL。该命令需要使用管理员权限执行。也可以在Windows上使用mklink创建符号链接。

看看维基吧。

对于那些在Windows Vista、Windows 7或更高版本上使用Cygwin的人来说,原生git命令可以创建“适当的”符号链接,这些符号链接可以被Windows应用程序(如Android Studio)识别。你只需要设置CYGWIN环境变量来包含winsymlinks:native或winsymlinks:nativestrict,就像这样:

export CYGWIN="$CYGWIN winsymlinks:native"

这样做的缺点(也是一个很重要的缺点)是Cygwin shell必须是“以管理员身份运行”,这样它才能拥有创建这些符号链接所需的操作系统权限。但是,一旦创建了它们,就不需要特殊的权限来使用它们。只要它们没有在存储库中被另一个开发人员更改,git就可以在正常的用户权限下正常运行。

就我个人而言,我只对Windows应用程序(即非cygwin)导航的符号链接使用这种方法,因为这增加了难度。

有关此选项的更多信息,请参阅堆栈溢出问题:如何在Windows 7中使用Cygwin创建符号链接