git: 由于权限问题,无法推送(解包器错误)

71
我在尝试推送到Git时遇到了这个问题。
error: insufficient permission for adding an object to repository database ./objects

fatal: failed to write object
error: unpack failed: unpack-objects abnormal exit
To ssh://<repo url>/<repo dir>
 ! [remote rejected] master -> master (n/a (unpacker error))
error: failed to push some refs to 'ssh://<repo url>/<repo dir>'

我以前偶尔遇到过这个问题,我们总是不得不通过每个用户通过ssh访问仓库,并在其中的所有文件上设置组权限来解决它。
chmod -R g+w *

这从来都不是一个令人满意的解决方案,现在它给我们带来了麻烦,因为其中一个人不在,没有人知道他的仓库用户密码。所以,我正在尝试正确解决这个问题。
错误似乎发生在有人试图推送一个将改变由另一个用户拥有的仓库目录的更改时(因此在上面设置了组写入选项)。我在这方面做了一些谷歌搜索,并找到了几种正在讨论的解决方案(但对我都没有起作用)。
1. 确保仓库目录共享的组是每个用户的主要组(我相信这已经是这样了:每个用户只有一个组,所以那一定是他们的主要组,对吗?) 2. git仓库的core.sharedRepository设置,详见这里:Git: Can't push from one computer 我已经更改了这个设置,但没有任何改变。我需要重新加载配置或者做些其他操作才能生效吗?
这是我目前的仓库配置:
[core]
        repositoryformatversion = 0
        filemode = true
        bare = true
        sharedRepository = all
[receive]
        denyNonFastForwards = True

非常感谢任何建议或建议! Max

你能提供一个最小化的测试仓库来重现这个问题吗?如果仓库中有一个名为.GIT(大写)的目录,我总是可以得到它。 - Ciro Santilli OurBigBook.com
这也可能是由于磁盘已满,而不一定是权限问题! - GH05T
这对我来说很有效: https://dev59.com/IVkS5IYBdhLWcg3w253q#69334361 - akbar
16个回答

41

这个错误发生了两周,大部分的解决方案都提到了'chmod -R',但不幸的是我使用的 Git 存储库(本地 / 远程 / 共享 - 与团队一起)都在 Windows 操作系统上。即使 chmod -Rv 显示所有文件都已更改为'rwxrwxrwx',随后的 'ls -l' 仍然显示所有文件为'rwxr-xr-x',而且错误重复出现。最终,我看到了 Ariejan de Vroom 的这个解决方案。它有效了,我们都能够再次拉取和推送。

在本地(无法推送的本地)和远程存储库上运行以下命令:

$ git fsck
$ git prune
$ git repack
$ git fsck

顺便说一下,我尝试使用Windows本地文件权限/ACL,甚至将问题用户提升为管理员,但似乎都没有帮助。不确定环境是否重要,但它可能会对具有类似设置的人有所帮助-困扰团队成员和远程(Windows Server 2008 R2标准版),我的本地机器是Windows 7虚拟机。


2
当出现git文件系统损坏的情况时,存在这种错误情况,这些指令有助于纠正它。谢谢。 - nkadwa
@nkadwa,我很高兴这能帮到你。 - Jason Robinson
1
由于这是唯一的答案,也涉及到Windows。作为非特权用户,在Windows 10上我遇到了完全相同的问题。简单的git pull解决了它。 - Markus

30

更简单的方法是添加一个 post-receive 脚本,每次向服务器上的 'hub' 存储库推送后运行 chmod 命令。在服务器上的 git 文件夹内的 hooks/post-receive 中添加以下行:

chmod -Rf u+w /path/to/git/repo/objects

谢谢您的回答,我一直在处理同样的问题,但不想设置整个存储库管理包来处理它。 - Kelly
3
这个针对我有效的后接收脚本是:chown -R git:git /home/git/repositories/myrepo.git/objects/。 - fjsj
4
可能是所有者的问题,如果远程存储库中的某些文件夹/文件被另一个远程用户修改/创建,该用户与推送者不同。 - Fedir RYKHTIK
我个人一直使用同一个用户作为管理员,但有些对象的所有者似乎已经被篡改了。我使用 chown -R 来修复它。 - Pierre de LESPINAY

9

这是一个权限错误。对我来说最合适和安全的方法是将用户添加到存储库所属的附加组中(或反之亦然):添加用户到附加组

groupadd git
chgrp -R git .git
chgrp -R git ./
usermod -G -a git $(whoami)

3
为了避免将用户从所有组中移除,除了 git 组之外,应该使用 usermod -G -a ...,这样正确吗? - chris
1
哇...我简直不敢相信我错过了那个,我希望给点赞的人没有受到困惑的后果。谢谢,@chris - Alastair
1
在我的系统上执行 usermod -a -G ... 后,我必须注销并重新登录才能看到更改。 - Andy J

8

如果还有其他人也遇到了这个问题:这只是意味着你要推送的仓库的写入权限不正确。去进行chmod -R操作,以便使用git服务器的用户具有写入权限。


9
请在Stack Overflow上发布外部答案的内容:以防外部链接失效的情况。 - ThorSummoner
4
正如@ThorSummoner所提到的,最好将博客内容放到这篇帖子中。链接现在已经过时了。 - colidyre
1
链接已经完全失效。 - Andy J

5
对于我来说,当我远程空间耗尽时,就会出现这个错误。
我只需要阅读剩余的错误信息即可:
error: file write error (No space left on device)
fatal: unable to write sha1 file
error: unpack failed: unpack-objects abnormal exit

4

对于在AWS实例上使用git存储库时出现的权限错误,我通过创建一个组并将其递归地分配到存储库文件夹中,并为该组赋予写入权限,然后将默认的aws实例用户(ec2-user或ubuntu)分配给该组来成功解决了该问题。

1. 创建一个名为share_group或其他名称的组

     sudo groupadd share_group

2. 将仓库文件夹从“root”组更改为“share_group”

     sudo chgrp -R share_group /path/to/your/repository

3. 给 share_group 添加写权限

     sudo chmod -R g+w /path/to/your/repository

4. 最后一步是将当前用户——默认情况下ec2是'ec2-user',ubuntu实例上的用户是'ubuntu'(在AWS上)——分配到share_group。我正在使用AWS上的ubuntu实例,所以我的默认用户是ubuntu。

     sudo usermod -a -G share_group ubuntu

顺便提一下,要查看文件夹或文件的所有权,请输入以下命令:

    ls -l  /path/to/your/repository

'

输出:

    drwxr-x--x  2 root shared_group
https://wiki.archlinux.org/index.php/File_permissions_and_attributes 在第三步之后,您将看到


    drwx--x--x  2 root root

改为

    drwxr-x--x  2 root share_group 

在这种情况下,出于安全考虑,我没有将用户“ubuntu”分配给root组。您可以根据第4步尝试将默认用户分配给root(只需跳过前3步)。

另一种方法是,通过以下方式尝试解决:

    chmod -Rf u+w /path/to/git/repo/objects

最终,下面的代码对我来说肯定有效,但777对于安全性不好

    sudo chmod -R 777 /path/to/your/repo

sudo chmod -R 777 /path/to/your/repo 这个命令行可以正常工作 :) - Rakesh K

3

我使用gitosis来管理这种类型的事情。 Gitosis有一个单一的用户(通常称为“git”),拥有所有存储库,并使用基于公钥的访问控制来管理每个存储库。它可能不适合您的设置,但值得一试(没有双关语)。


1
还有一个叫做gitolite(http://github.com/sitaramc/gitolite)的工具,它是gitosis的一种更新和改进版本。 - ebneter
谢谢大家。但是我需要使用gitosis/gitolite从头开始重建我的repo吗? - Max Williams
1
不需要创建一个新的gitosis仓库,只需将您现有的头部推送到gitosis仓库中,或将您的仓库目录复制到gitosis创建的目录中即可。 - Cameron Skinner

2
我遇到了类似的错误,请看下面我是如何解决的。
我的目录结构: /opt/git/project.git Git用户是git。
$ cd /opt/git/project.git
$ sudo chown -R git:git .

使用 -R 选项的 chown 命令可以递归地更改当前目录的所有者和组(因为我在上面的命令中键入了 git:git)。由于 git 在将文件推送到存储库时会更改 git 目录中的许多文件,因此需要使用 chown -R。


2

这个问题也可能发生在需要重新启动的Ubuntu升级后。

如果文件/var/run/reboot-required存在,请立即或安排重新启动。


1

我也遇到了类似的问题,以为我的远程gitolite-admin被破坏或者有什么问题。

我的环境是Mac OS X(10.6.6)笔记本,远程运行Ubuntu 10服务器和gitolite。

结果问题出在我本地的gitolite-admin检出上。

尽管出现了“unpack failed”的错误信息,但事实证明这是本地的问题。

我通过再次检出它作为gitolite-admin2,并进行更改和推送来解决了这个问题。

瞧!它奏效了!


1
对我来说,问题也出在本地仓库上(可能是因为我在新版本的.git结构上使用了旧版本的git)。 git push无法工作,但git clone可以,所以我克隆了我的本地仓库,然后将新的.git移植到了本地仓库中。感谢提示! - Robert Hensing

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接