git 在 Windows 和 Linux 之间切换后强制刷新索引

问题描述 投票:0回答:5

我有一个Windows和Linux共享的磁盘分区(格式:NTFS)。它包含一个 git 存储库(大约 6.7 GB)。 如果我仅使用 Windows仅使用 Linux 来操作 git 存储库,一切都很好。 但是我每次切换系统,

git status
命令都会刷新索引,大概需要1分钟。如果我再次在同一个系统中运行
git status
,只需要不到 1 秒。这是结果

# Just after switch from windows
[#5#wangx@manjaro:duishang_design] git status  # this command takes more than 60s
Refresh index: 100% (2751/2751), done.
On branch master
nothing to commit, working tree clean

[#10#wangx@manjaro:duishang_design] git status  # this time the command takes less than 1s
On branch master
nothing to commit, working tree clean

[#11#wangx@manjaro:duishang_design] git status  # this time the command takes less than 1s
On branch master
nothing to commit, working tree clean

我猜git缓存有问题。例如:Windows和Linux都使用

.git/index
文件作为缓存文件,但是Linux系统中的git无法识别Windows更改的
.git/index
。所以它只能刷新索引并替换
.git/index
文件,这使得接下来的
git status
超快而Windows中的
git status
非常慢(因为Windows系统会重新刷新索引文件)

我的猜测正确吗?如果是这样,我如何为不同的系统设置索引文件?我该如何解决这个问题?

linux windows git interop git-index
5个回答
36
投票

你在这里完全正确:

  • 你在这里使用的东西,Git 称之为 indexstaging areacache,实际上包含缓存数据。

  • 它包含的缓存数据是系统调用的结果。

  • Linux系统返回的系统调用数据与Windows系统返回的系统调用数据不同

因此,操作系统切换完全使所有缓存数据无效。

...如何为不同的系统设置索引文件?

你最好的选择是根本不要这样做。创建两个不同的工作树,或者甚至两个不同的存储库。但是,如果这比其他选择更痛苦,请尝试这些想法:

Git 使用的实际索引文件仅默认为

.git/index
。您可以通过将 GIT_INDEX_FILE 设置为其他(相对或绝对)路径来指定
different
文件。所以你可以有
.git/index-linux
.git/index-windows
,并根据你使用的操作系统设置
GIT_INDEX_FILE

一些 Git 命令使用临时索引。他们通过自己设置

GIT_INDEX_FILE
来做到这一点。如果他们之后un-设置它,他们可能会在此时意外使用
.git/index
。因此,另一种选择是在切换操作系统时 重命名
.git/index
。像以前一样保留
.git/index-windows
.git/index-linux
,但是在使用时将正在使用的一个重命名为
.git/index
,然后在切换到另一个系统之前将其重命名为
.git/index-name

再次强调,我不建议尝试这两种方法中的任何一种,但它们或多或少可能会奏效。


11
投票

正如 torek 提到的,您可能不想这样做。在操作系统之间共享存储库通常不是一个好主意。

但是,这是可能的,就像在 Windows 和 Windows 子系统 for Linux 之间共享存储库一样。您可能想尝试将

core.checkStat
设置为
minimal
,如果这还不够,请将
core.trustctime
设置为
false
。这导致索引中存储的信息量最少,这意味着数据将尽可能便携。

但是请注意,如果您的存储库具有符号链接,那么您所做的任何事情都可能无法阻止刷新。 Linux 通常认为符号链接的长度是以字节为单位的长度,而 Windows 认为它占用一个或多个磁盘块,因此操作系统之间的大小会不匹配。这是不可避免的,因为大小是索引中使用的无法禁用的属性之一。


6
投票

这可能不适用于原始海报,但如果在 Windows Linux 子系统 (WSL) 下使用 Linux,那么即使在 Linux 端也可以使用

git.exe
快速修复。使用别名或其他东西使其无缝。例如:

alias git=git.exe

4
投票

Auto line ending setting 解决了我在this discussion中的问题。我指的是 Windows、WSL2、便携式 Linux 操作系统和 Linux,以及我已根据工作要求设置和运行的 Linux。我会更新以防遇到任何问题,同时更喜欢这种从不同文件系统(NTFS 或 Linux 文件系统)更新代码库的方法。

git config --global core.autocrlf true 

0
投票

在我的例子中,我只是不希望在 docker 容器中运行的命令(并调用

git status
以查明工作目录是否干净)在容器外修改
.git/index
,所以我正在执行命令在运行
.git/index
.
之前制作
GIT_INDEX_FILE=my_index_copy git status

的临时副本

在我的例子中

.git/index
大约是 1 MB,这足够小以至于即使复制该文件花费了额外的时间(特别是考虑“刷新索引...”需要多长时间),命令仍然相当快。

© www.soinside.com 2019 - 2024. All rights reserved.