从git克隆后,Windows符号链接变得无效。

11 浏览
0 Comments

从git克隆后,Windows符号链接变得无效。

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

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

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

我尚未实施此解决方案,但我相信这是一个解决这个问题的可靠方法。

  1. 您认为这种方法有哪些缺点(如果有的话)?
  2. 这个后检出脚本是否可行?即,我能否递归查找Git创建的虚拟“symlink”文件?
0
0 Comments

Windows symbolic link become invalid after clone from git

在使用git克隆项目时,Windows系统中的符号链接可能会变得无效。解决方法是找到这些无效的符号链接,并替换它们。

可以使用以下命令查找具有模式120000的文件,可能是这样的命令:

git ls-files -s | awk '/120000/{print $4}'

一旦替换了这些链接,建议使用git update-index --assume-unchanged将它们标记为未更改,而不是将它们列在.git/info/exclude文件中。

如果您在msysgit中使用awk命令时遇到问题,可以将awk替换为gawk,其他情况下应该可以正常工作。

有人要求分享使用mklink在Windows上检查符号链接文本文件并将其替换为符号链接的脚本,但是--assume-unchanged部分似乎无效。切换到另一个分支时,git会说符号链接文件已更改,需要先提交,但是git status命令却显示没有更改。对此有什么想法吗?

有人提供了一个PowerShell脚本,可以使用mklink来检查并替换符号链接:gist.github.com/ferventcoder/7995025

有人指出上述脚本只是忽略了文件,而没有将其解析为应有的符号链接。

另外,这是两年前的评论,可能不适用于当前情况。

还有一种更可移植和技术上更准确的方法:git ls-files -s | grep '^12',但是对于脚本来说不太好用,因为它没有去除前三列数据,只留下了要操作的文件名列表。

还有更可移植的方法可以打印第四列,而不是使用GNU awk。例如:git ls-files -s | grep '^12' | cut -f2(第二个以制表符分隔的列;其他列以空格分隔)。

对于Cygwin/bash的一行命令,可以将所有符号链接标记为未更改:for f in `git ls-files -s | awk '/120000/{print $4}'`; do git update-index --assume-unchanged $f; done

在Windows上,符号链接存储了完整路径,因此每次检出项目时都需要创建自己的符号链接,已经在存储库中存在的版本是无用的。因此,与其将其标记为未更改,不如将其添加到.gitignore文件中更好,尽管我没有进行比较测试。

总结提出的一行代码的问题:如果文件名包含"120000",则失败(正则表达式需要一个^),如果符号链接文件名包含空格,则失败。Zenexer提供的使用grep和cut的解决方案没有这些问题。

0
0 Comments

Windows symbolic link become invalid after clone from git的问题出现的原因是:

1. Windows系统未启用开发人员模式,导致没有权限使用mklink命令创建符号链接。

2. 在git中未启用符号链接功能。

解决方法如下:

1. 在Windows 10/11中启用“开发人员模式”以获得mklink权限。

2. 在git中启用符号链接功能,可以选择以下任一方法:

- 在安装msysgit时勾选“使用符号链接”选项。

- 使用全局设置命令git config --global core.symlinks true启用符号链接。

- 使用本地设置命令git config core.symlinks true启用符号链接。

需要注意的是,由于Windows上对git的符号链接支持相对较新,一些git客户端仍然存在一些问题。特别是,由于libgit2中的回归问题,使用相对路径(..)的符号链接在某些程序中可能会损坏。例如,GitKraken受到此问题的影响,因为他们正在等待nodegit将libgit2从v0.x(存在回归问题)更新到v1.x(已修复)。

如果遇到符号链接丢失或损坏的情况,可以尝试以下方法进行修复:

- 使用git checkout -- path/to/symlink命令进行checkout。

- 使用git restore -- path/to/symlink命令进行恢复(适用于git v2.23.0及以上版本)。

- 切换分支(切换到其他分支再切回来)。

- 使用git reset --hard命令进行硬重置。

- 删除本地仓库并重新克隆。

如果遇到问题,可以通过git config --show-scope --show-origin core.symlinks命令查看符号链接配置的级别、配置文件和当前值。可能存在本地配置覆盖全局或系统设置的情况,可以使用git config --unset core.symlinks命令清除本地设置,以使更高级别的设置生效。

另外,有用户反馈需要重新克隆仓库才能使符号链接正常工作。如果不想重新克隆,修复仓库的配置可能已足够。可以运行git config --unset core.symlinks命令来清除仓库中的core.symlinks配置(注意没有--global选项)。

如果不想启用开发人员模式,也可以通过按下Win + R,输入gpedit.msc,打开本地组策略编辑器,在“本地策略”->“用户权限分配”->“创建符号链接”中添加用户账号来设置符号链接权限。

以上就是解决Windows从git克隆后符号链接失效的问题的方法。

0
0 Comments

在克隆git存储库后,Windows符号链接无效的问题可能是由于以下原因引起的:

1. Windows系统对符号链接的支持有限,无法正确处理git存储库中的符号链接。

2. 克隆git存储库时,符号链接的元数据可能没有正确地传输到Windows系统上。

针对这个问题,可以尝试以下解决方法:

1. 在Windows系统上更新mklink命令的理解,并打开开发者模式。这可以通过在命令提示符中运行以下命令来实现:git config --global core.symlinks true

2. 创建一个git别名来处理符号链接。可以在git的全局配置中添加以下别名:

 git config --global alias.add-symlink '!'"$(cat <<'ETX'
 __git_add_symlink() {
   if [ $# -ne 2 ] || [ "$1" = "-h" ]; then
     printf '%b\n' \
         'usage: git add-symlink <source_file_or_dir> <target_symlink>\n' \
         'Create a symlink in a git repository on a Windows host.\n' \
         'Note: source MUST be a path relative to the location of target'
     [ "$1" = "-h" ] && return 0 || return 2
   fi
   source_file_or_dir=${1#./}
   source_file_or_dir=${source_file_or_dir%/}
   target_symlink=${2#./}
   target_symlink=${target_symlink%/}
   target_symlink="${GIT_PREFIX}${target_symlink}"
   target_symlink=${target_symlink%/.}
   : "${target_symlink:=.}"
   if [ -d "$target_symlink" ]; then
     target_symlink="${target_symlink%/}/${source_file_or_dir##*/}"
   fi
   case "$target_symlink" in
     (*/*) target_dir=${target_symlink%/*} ;;
     (*) target_dir=$GIT_PREFIX ;;
   esac
   target_dir=$(cd "$target_dir" && pwd)
   if [ ! -e "${target_dir}/${source_file_or_dir}" ]; then
     printf 'error: git-add-symlink: %s: No such file or directory\n' \
         "${target_dir}/${source_file_or_dir}" >&2
     printf '(Source MUST be a path relative to the location of target!)\n' >&2
     return 2
   fi
   git update-index --add --cacheinfo 120000 \
       "$(printf '%s' "$source_file_or_dir" | git hash-object -w --stdin)" \
       "${target_symlink}" \
     && git checkout -- "$target_symlink" \
     && printf '%s -> %s\n' "${target_symlink#$GIT_PREFIX}" "$source_file_or_dir" \
     || return $?
 }
 __git_add_symlink
 ETX
 )"

使用git add-symlink <source_file_or_dir> <target_symlink>命令来创建符号链接。其中,source_file_or_dir是相对于目标符号链接位置的路径。

3. 创建一个git别名来替换git符号链接为NTFS硬链接或junctions。可以在git的全局配置中添加以下别名:

 git config --global alias.rm-symlinks '!'"$(cat <<'ETX'
 __git_rm_symlinks() {
   case "$1" in (-h)
     printf 'usage: git rm-symlinks [symlink] [symlink] [...]\n'
     return 0
   esac
   ppid=$$
   case $# in
     (0) git ls-files -s | grep -E '^120000' | cut -f2 ;;
     (*) printf '%s\n' "$@" ;;
   esac | while IFS= read -r symlink; do
     case "$symlink" in
       (*/*) symdir=${symlink%/*} ;;
       (*) symdir=. ;;
     esac
     git checkout -- "$symlink"
     src="${symdir}/$(cat "$symlink")"
     posix_to_dos_sed='s_^/\([A-Za-z]\)_\1:_;s_/_\\\\_g'
     doslnk=$(printf '%s\n' "$symlink" | sed "$posix_to_dos_sed")
     dossrc=$(printf '%s\n' "$src" | sed "$posix_to_dos_sed")
     if [ -f "$src" ]; then
       rm -f "$symlink"
       cmd //C mklink //H "$doslnk" "$dossrc"
     elif [ -d "$src" ]; then
       rm -f "$symlink"
       cmd //C mklink //J "$doslnk" "$dossrc"
     else
       printf 'error: git-rm-symlink: Not a valid source\n' >&2
       printf '%s =/=> %s  (%s =/=> %s)...\n' \
           "$symlink" "$src" "$doslnk" "$dossrc" >&2
       false
     fi || printf 'ESC[%d]: %d\n' "$ppid" "$?"
     git update-index --assume-unchanged "$symlink"
   done | awk '
     BEGIN { status_code = 0 }
     /^ESC\['"$ppid"'\]: / { status_code = $2 ; next }
     { print }
     END { exit status_code }
   '
 }
 __git_rm_symlinks
 ETX
 )"

使用git rm-symlinks [symlink] [symlink] [...]命令来替换git符号链接为NTFS硬链接或junctions。

4. 创建一个git别名来恢复git符号链接。可以在git的全局配置中添加以下别名:

 git config --global alias.checkout-symlinks '!'"$(cat <<'ETX'
 __git_checkout_symlinks() {
   case "$1" in (-h)
     printf 'usage: git checkout-symlinks [symlink] [symlink] [...]\n'
     return 0
   esac
   case $# in
     (0) git ls-files -s | grep -E '^120000' | cut -f2 ;;
     (*) printf '%s\n' "$@" ;;
   esac | while IFS= read -r symlink; do
     git update-index --no-assume-unchanged "$symlink"
     rmdir "$symlink" >/dev/null 2>&1
     git checkout -- "$symlink"
     printf 'Restored git symlink: %s -> %s\n' "$symlink" "$(cat "$symlink")"
   done
 }
 __git_checkout_symlinks
 ETX
 )"

使用git checkout-symlinks [symlink] [symlink] [...]命令来恢复git符号链接。

需要注意的是,使用这些解决方法可能存在一些限制:

1. 路径中含有空格的目录/文件/符号链接可能无法正常工作。

2. 如果在执行像git add -A这样可能有广泛影响的操作之前忘记执行git checkout-symlinks,本地存储库可能会处于污染状态。

为了避免这些限制,可以在Windows用户构建项目之前和之后,将这些别名作为步骤包含在内。

0