在 Windows 和 WSL 之间共享 git 回购符号链接
Sharing git repo symlinks between Windows and WSL
我有以下设置:
- WSL 安装 Ubuntu,git 已安装
- git 从 Windows 端的 https://git-scm.com 安装
- 通过打开开发人员模式并将我的用户添加到正确的策略组来启用符号链接创建,如 https://github.com/git-for-windows/git/wiki/Symbolic-Links
中所述
core.symlinks=true
(由于上面的行)
core.autocrlf=false
(我不想git做任何小聪明,我在Windows和WSL之间共享repo)
这个几乎 工作完美(印象深刻)。当我克隆一个存储库时,在 Windows 和 WSL 中都可以,除了两侧之一的符号链接说它们被修改但实际上没有。在两侧,符号链接 工作 正确,我可以毫无问题地导航它们。
初始克隆后(在 Windows 端),Windows PowerShell 给出:
PS C:\Users\Matthew\Projects\...> git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
然而在WSL这边,它说修改了两个符号链接:
/mnt/c/Users/Matthew/Projects/...$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: t/browser
modified: web/jslib
no changes added to commit
但是 git diff 没有输出:
/mnt/c/Users/Matthew/Projects/...$ git diff
/mnt/c/Users/Matthew/Projects/...$
如果我随后在 WSL 端重置结帐,它就会全部切换:
/mnt/c/Users/Matthew/Projects/...$ git reset --hard HEAD
HEAD is now at ......... Commit message here
/mnt/c/Users/Matthew/Projects/...$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
然后返回 Windows Powershell:
PS C:\Users\Matthew\Projects\...> git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: t/browser
modified: web/jslib
no changes added to commit (use "git add" and/or "git commit -a")
PS C:\Users\Matthew\Projects\...> git diff
PS C:\Users\Matthew\Projects\...>
似乎 git 正在设置一个内部标志,然后它认为在另一个系统中发生了变化;有什么办法可以解决或解决这个问题吗?
出现此问题是因为 Windows 和 Linux(或至少是模拟版本)不同意符号链接的大小。在 Windows,符号链接的大小以块为单位,因此 6 个字符的符号链接的大小为 4096 字节。在 Linux 上,符号链接的大小是它包含的字节数(在本例中为 6)。
Git 写入索引以跟踪文件是否已更改的其中一项是大小。当您执行任何类型的索引更新时,例如 git reset --hard
,Git 会将所有这些元数据写入索引,包括大小。当您 运行 git status
、git 检查此元数据以确定它是否匹配时,如果不匹配,它会将文件标记为已修改。
可以控制是否在索引中检查某些信息,因为某些工具会产生虚假信息(例如,JGit 不写入设备和 inode 编号),但大小始终是检查,因为它被视为文件是否已更改的良好指标。
因为这是 Windows 和 WSL 如何看待符号链接之间的根本分歧,所以这确实无法解决。您可以尝试询问 Git for Windows 项目是否愿意在 Git for Windows 中解决此问题,但我怀疑答案可能是否,因为更改它可能会对所有 Windows 用户产生性能影响。
找到解决方法。我在 wsl 中为 windows 创建了 Git 的别名:alias git="/mnt/c/Program\ Files/Git/bin/git.exe"。工作完美!
我有以下设置:
- WSL 安装 Ubuntu,git 已安装
- git 从 Windows 端的 https://git-scm.com 安装
- 通过打开开发人员模式并将我的用户添加到正确的策略组来启用符号链接创建,如 https://github.com/git-for-windows/git/wiki/Symbolic-Links 中所述
core.symlinks=true
(由于上面的行)core.autocrlf=false
(我不想git做任何小聪明,我在Windows和WSL之间共享repo)
这个几乎 工作完美(印象深刻)。当我克隆一个存储库时,在 Windows 和 WSL 中都可以,除了两侧之一的符号链接说它们被修改但实际上没有。在两侧,符号链接 工作 正确,我可以毫无问题地导航它们。
初始克隆后(在 Windows 端),Windows PowerShell 给出:
PS C:\Users\Matthew\Projects\...> git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
然而在WSL这边,它说修改了两个符号链接:
/mnt/c/Users/Matthew/Projects/...$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: t/browser
modified: web/jslib
no changes added to commit
但是 git diff 没有输出:
/mnt/c/Users/Matthew/Projects/...$ git diff
/mnt/c/Users/Matthew/Projects/...$
如果我随后在 WSL 端重置结帐,它就会全部切换:
/mnt/c/Users/Matthew/Projects/...$ git reset --hard HEAD
HEAD is now at ......... Commit message here
/mnt/c/Users/Matthew/Projects/...$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
然后返回 Windows Powershell:
PS C:\Users\Matthew\Projects\...> git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: t/browser
modified: web/jslib
no changes added to commit (use "git add" and/or "git commit -a")
PS C:\Users\Matthew\Projects\...> git diff
PS C:\Users\Matthew\Projects\...>
似乎 git 正在设置一个内部标志,然后它认为在另一个系统中发生了变化;有什么办法可以解决或解决这个问题吗?
出现此问题是因为 Windows 和 Linux(或至少是模拟版本)不同意符号链接的大小。在 Windows,符号链接的大小以块为单位,因此 6 个字符的符号链接的大小为 4096 字节。在 Linux 上,符号链接的大小是它包含的字节数(在本例中为 6)。
Git 写入索引以跟踪文件是否已更改的其中一项是大小。当您执行任何类型的索引更新时,例如 git reset --hard
,Git 会将所有这些元数据写入索引,包括大小。当您 运行 git status
、git 检查此元数据以确定它是否匹配时,如果不匹配,它会将文件标记为已修改。
可以控制是否在索引中检查某些信息,因为某些工具会产生虚假信息(例如,JGit 不写入设备和 inode 编号),但大小始终是检查,因为它被视为文件是否已更改的良好指标。
因为这是 Windows 和 WSL 如何看待符号链接之间的根本分歧,所以这确实无法解决。您可以尝试询问 Git for Windows 项目是否愿意在 Git for Windows 中解决此问题,但我怀疑答案可能是否,因为更改它可能会对所有 Windows 用户产生性能影响。
找到解决方法。我在 wsl 中为 windows 创建了 Git 的别名:alias git="/mnt/c/Program\ Files/Git/bin/git.exe"。工作完美!