在SD卡上的WSL中,git没有足够的权限添加对象

在SD卡上的WSL中,git没有足够的权限添加对象,git,ubuntu,unix,windows-subsystem-for-linux,fstab,Git,Ubuntu,Unix,Windows Subsystem For Linux,Fstab,我试图让Git在我的系统上工作,但我总是会出错 错误:将对象添加到存储库数据库的权限不足……/.git/objects 我正在使用Ubuntu开发Windows Linux子系统中的Surface Pro 5。 如果我在内部驱动器上工作,一切正常。 当我想在micro SD卡上工作时,问题就开始了。 首先,它不是自动安装的。 我通过编辑/etc/fstab文件修复了这个问题: E:/mnt/E drvfs默认值、元数据、rw、exec、uid=nico、gid=nico 0 并且ls-alR显示

我试图让Git在我的系统上工作,但我总是会出错

错误:将对象添加到存储库数据库的权限不足……/.git/objects

我正在使用Ubuntu开发Windows Linux子系统中的Surface Pro 5。 如果我在内部驱动器上工作,一切正常。 当我想在micro SD卡上工作时,问题就开始了。 首先,它不是自动安装的。 我通过编辑
/etc/fstab
文件修复了这个问题:

E:/mnt/E drvfs默认值、元数据、rw、exec、uid=nico、gid=nico 0

并且
ls-alR
显示所有用户和所有文件的权限都应该是rw

我在SD卡上的现有存储库上尝试了
git add
,但没有成功。 不知怎的,它在“.git/objects/54/”中创建了一个tmp文件,每次我尝试它时它都没有写权限

然后我尝试克隆一个测试存储库,但它创建了一个splitsec文件夹,并给了我相同的错误。它在我的普通硬盘上工作,但在我的SD卡上不工作

nico@DESKTOP-639MEJ9:/mnt/e$ git clone https://github.com/NicoJG/TestGit.git
Cloning into 'TestGit'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
error: insufficient permission for adding an object to repository database /mnt/e/TestGit/.git/objects
fatal: failed to write object
fatal: unpack-objects failed
nico@DESKTOP-639MEJ9:/mnt/e$ sudo git clone https://github.com/NicoJG/TestGit.git
[sudo] password for nico:
Cloning into 'TestGit'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
error: insufficient permission for adding an object to repository database /mnt/e/TestGit/.git/objects
fatal: failed to write object
fatal: unpack-objects failed
nico@DESKTOP-639MEJ9:/mnt/e$
git在WSL中的权限无法正常工作。 我已经试过了:

sudo chmod -R ug+rw *
sudo chwn -R nico:nico *
有人知道怎么修吗

编辑:根据bk2204的要求,这里是装载的输出:

nico@DESKTOP-639MEJ9:/mnt/e$ mount
rootfs on / type lxfs (rw,noatime)
none on /dev type tmpfs (rw,noatime,mode=755)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)
devpts on /dev/pts type devpts (rw,nosuid,noexec,noatime,gid=5,mode=620)
none on /run type tmpfs (rw,nosuid,noexec,noatime,mode=755)
none on /run/lock type tmpfs (rw,nosuid,nodev,noexec,noatime)
none on /run/shm type tmpfs (rw,nosuid,nodev,noatime)
none on /run/user type tmpfs (rw,nosuid,nodev,noexec,noatime,mode=755)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
cgroup on /sys/fs/cgroup type tmpfs (rw,relatime,mode=755)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,relatime,devices)
E: on /mnt/e type drvfs (rw,relatime,uid=1000,gid=1000,case=off)
C:\ on /windir/c type drvfs (rw,noatime,uid=1000,gid=1000,umask=22,fmask=11,metadata,case=off)

我只知道C:(我的主驱动器)和E:(我的SD卡)是什么。我想剩下的似乎是WSL特有的。

我也有同样的问题

背景

在最新的Windows版本中,WSL在如何与文件系统交互方面有一些更改。一个问题是,以前,Windows和Linux文件系统之间的不兼容意味着大多数文件在外部存储上实际上拥有“777”权限,因此任何用户都可以读取/写入/执行任何内容。这对于Linux来说并不理想,因为您不能存储私钥等。Microsoft现在已经改变了这种行为,通过扩展属性,文件可以同时具有Windows(NTFS)和Linux权限。在普通驱动器上,可以使用以下命令装载带有元数据的驱动器:

umount /mnt/c;
mount -t drvfs C:\\ /mnt/c/ -o metadata
不幸的是,他们似乎也将这一变化推广到了网络和外部文件系统(如
exFAT
),因为它们没有可扩展的属性,并且有点混乱,使得外部驱动器无法使用。例如,如果文件在Windows中是只读的,那么您不能在WSL中对其进行写入;您也不能用
sudo
覆盖它,因为Windows权限无论如何都会覆盖WSL权限。这些更改破坏了很多程序,我今天发现这些程序试图将更改上传到git。这是一个在互联网上还没有解决方案的新问题,所以我附上了一个文件来解决这个问题

要运行,请首先编译共享对象:

cc -Wall -O3 -D_GNU_SOURCE -fPIC -c -o githack.o githack.c; gcc -o githack.so -nostartfiles -shared githack.o -ldl;
然后运行前缀为
LD\u PRELOAD
的命令:

LD_PRELOAD=./githack.so git commit -a -m "Another interesting commit"
如何调查其他项目

对于
git
,具体问题如下:

error: insufficient permission for adding an object to repository database .git/objects
要找出失败的原因,可以使用
strace

strace git commit -a -m "Another interesting commit"

>

...

gettimeofday({tv_sec=1592618056, tv_usec=52991}, NULL) = 0

getpid()                               = 651

openat(AT_FDCWD, ".git/objects/78/tmp_obj_flbKNc", O_RDWR|O_CREAT|O_EXCL, 0444) = -1 EACCES (Permission denied)

write(2, "error: insufficient permission f"..., 88error: insufficient permission for adding an object to repository database .git/objects

) = 88

close(4)                               = 0

...
ltrace git commit -a -m "Latest local copy"

>

...

open64(".git/objects/78/tmp_obj_zDayCc", 194, 0444)                                                                                                         = -1

__errno_location()                                                                                                                                          = 0x7f2777001000

__errno_location()                                                                                                                                          = 0x7f2777001000

__vsnprintf_chk(0x7fffd4786d00, 4096, 1, 4096)                                                                                                              = 80

__fprintf_chk(0x7f277631c680, 1, 0x7f27773eacfc, 0x7f27773c8083error: insufficient permission for adding an object to repository database .git/objects

)                                                                                            = 88

close(4)

...
在打印错误行之前,我们立即了解它失败的原因(
-1
),因此修复它需要拦截该调用。您可以通过
ltrace
确定:

strace git commit -a -m "Another interesting commit"

>

...

gettimeofday({tv_sec=1592618056, tv_usec=52991}, NULL) = 0

getpid()                               = 651

openat(AT_FDCWD, ".git/objects/78/tmp_obj_flbKNc", O_RDWR|O_CREAT|O_EXCL, 0444) = -1 EACCES (Permission denied)

write(2, "error: insufficient permission f"..., 88error: insufficient permission for adding an object to repository database .git/objects

) = 88

close(4)                               = 0

...
ltrace git commit -a -m "Latest local copy"

>

...

open64(".git/objects/78/tmp_obj_zDayCc", 194, 0444)                                                                                                         = -1

__errno_location()                                                                                                                                          = 0x7f2777001000

__errno_location()                                                                                                                                          = 0x7f2777001000

__vsnprintf_chk(0x7fffd4786d00, 4096, 1, 4096)                                                                                                              = 80

__fprintf_chk(0x7f277631c680, 1, 0x7f27773eacfc, 0x7f27773c8083error: insufficient permission for adding an object to repository database .git/objects

)                                                                                            = 88

close(4)

...
因此,本文底部的附加代码截取了标记为等于
194
open64
代码

解决方案代码(名称githack.c)

#包括
#包括
#包括
#包括
#包括
//#定义openat ignorethisopen
#定义打开忽略此打开
#定义open64忽略此open64
#包括
//#未定义开放
#未定义开放
#undef open64
#包括
/*
“strace git…”将在openat()命令上显示git失败
这可能在您的系统上实现为open64()
您可以使用“ltrace git…”来确认这一点
您可能还需要调整194的oflag比较
*/
/*静态int(*openat)(int,char*,int,mode\t)*/
静态整型(*打开)(常量字符*,整型,模式t);
静态整数(*open64)(常量字符*,整数,模式);
静态void*dlwrap(常量字符*fn)
{
常量字符*e;
void*p=dlsym(RTLD_NEXT,fn);
如果((e=dlerror())!=0)
fprintf(stderr,“dlsym(RTLD_NEXT,'%s'):%s\r\n”,fn,e);
返回p;
}
void _init(void)
{
___打开=dlwrap(“打开”);
___open64=dlwrap(“open64”);
}
/*int openat(int dirfd,const char*路径名,int of lag,mode\u t mode)*/
int open(常量字符*路径名、整型标签、模式)
{
如果(oflag&&oflag==194)
返回打开(路径名,oflag,S_IRWXU);
返回打开(路径名、oflag、模式);
}
int open64(常量字符*路径名,整数oflag,模式)
{
如果(oflag&&oflag==194)
返回open64(路径名,oflag,S_IRWXU);
返回open64(路径名、oflag、模式);
}

你能编辑你的问题以包含运行
挂载的输出吗?
你能用sudo完成吗?这是很多人都会发现的问题,因此为什么这么有趣:)