Git Push错误:向存储库数据库添加对象的权限不足

当我尝试推送到共享的git远程时,我收到以下错误: insufficient permission for adding an object to repository database

然后我在这里读到一个修复:修复这适用于下一次推送,因为所有文件都属于正确的组,但是下一次有人推送更改时,它在对象文件夹中创建了一个新项目,该项目将其默认组作为组。我唯一能想到的就是更改他们签入的项目的所有开发人员的默认组,但这似乎是一个黑客行为。有什么想法吗?谢谢。

600019 次浏览

修复权限

确定并修复潜在原因后(见下文),您将需要修复权限:

cd /path/to/repo/.git
sudo chgrp -R groupname .
sudo chmod -R g+rwX .
sudo find . -type d -exec chmod g+s '{}' +

请注意,如果您希望每个人都能够修改存储库,则不需要chgrp,您需要将chmod更改为sudo chmod -R a+rwX .

如果您不修复根本原因,错误将不断返回,您将不得不一遍又一遍地重新运行上述命令。

根本原因

错误可能由以下原因之一引起:

  • 存储库未配置为共享存储库(请参阅git help config中的core.sharedRepository)。如果:

     git config core.sharedRepository
    

    不是grouptrue1或一些掩码,请尝试运行:

     git config core.sharedRepository group
    

    然后重新运行递归的chmodchgrp(参见上面的“修复权限”)。

  • 操作系统不会将目录上的setgid位解释为“所有新文件和子目录都应该继承组所有者”。

    core.sharedRepositorytruegroup时,Git依赖于GNU操作系统的一个特性(例如,每个Linux发行版)来确保新创建的子目录归正确的组(存储库所有用户所在的组)所有。这个特性记录在GNU coreutils留档中:

    …[如果]设置了目录的set-group ID位,新创建的子文件将继承与目录相同的组,新创建的子目录将继承父目录的set-group ID位。…[这种机制让]用户更容易共享文件,减少了使用chmodchown共享新文件的需要。

    但是,并非所有操作系统都具有此功能(NetBSD就是一个例子)。对于这些操作系统,您应该确保所有Git用户都具有相同的默认组。或者,您可以通过运行git config core.sharedRepository world使存储库全域可写(但要小心-这不太安全)。

  • 文件系统不支持setgid位(例如,FAT)。ext2,ext3,ext4都支持setgid位。据我所知,不支持setgid位的文件系统也不支持组所有权的概念,因此所有文件和目录无论如何都将归同一个组所有(哪个组是挂载选项)。在这种情况下,确保所有Git用户都属于拥有文件系统中所有文件的组。

  • 并非所有Git用户都在拥有存储库目录的同一组中。确保目录上的组所有者是正确的,并且所有用户都在该组中。

一个很好的调试方法是下次发生时,SSH远程存储库,cd到对象文件夹并执行ls -al

如果您看到2-3个文件具有不同的user: group所有权,那么这就是问题所在。

我过去遇到过这种情况,一些遗留脚本访问我们的git repo,通常意味着不同的(unix)用户最后推送/修改文件,而您的用户没有覆盖这些文件的权限。您应该创建一个共享的git组,所有启用git的用户都在其中,然后递归地chgrpobjects文件夹及其内容,以便它的组所有权是共享的git组。

您还应该在文件夹上添加一个粘性位,以便在文件夹中创建的所有文件始终具有git组。

chmod g+s目录名称

更新:我不知道core.shared存储库。很高兴知道,尽管它可能只是做了上面的事情。

对于Ubuntu(或任何Linux)

从项目根,

cd .git/objects
ls -al
sudo chown -R yourname:yourgroup *

您可以通过以下方式告诉您的姓名和组:

# for yourname
whoami
# for yourgroup
id -g -n <yourname>

注意:记住sudo行末尾的星星

我只是想添加我的解决方案。我在OS X上有一个存储库,它在某些目录上拥有root的所有权,在其他目录上拥有Home(这是我的用户目录),导致上面列出的相同错误。

谢天谢地,解决方案很简单。从终端:

sudo chown -R Home projectdirectory

我遇到了同样的问题。阅读这里,我意识到消息所指的是文件权限。对我来说,修复方法是:

/etc/inetd.d/git-gpv

它以用户'没有人'启动git-daemon,因此缺乏写入权限。

# Who   When    What
# GPV   20Nov13 Created this by hand while reading: http://linuxclues.blogspot.co.uk/2013/06>/git-daemon-ssh-create-repository-debian.html
# GPV   20Nov13 Changed owner (to user_git) otherise nobody lack permission to update the repository
#git stream tcp nowait nobody  /usr/bin/git git daemon --inetd --verbose --enable=receive-pack --export-all /gitrepo
git stream tcp nowait user_git  /usr/bin/git git daemon --inetd --verbose --enable=receive-pack --export-all /gitrepo

(我怀疑其他调用他们的inetd conf文件git-gpv。通常它会直接在 /etc/inetd.conf)

在你添加一些东西之后…提交它们并在所有完成推送之后!砰!!开始所有问题…正如你应该注意到的那样,新项目和现有项目的定义方式存在一些差异。如果其他人尝试添加/提交/推送相同的文件或内容(git将两者保留为相同的对象),我们将面临以下错误:

$ git push
Counting objects: 31, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (17/17), done.
Writing objects: 100% (21/21), 2.07 KiB | 0 bytes/s, done.
Total 21 (delta 12), reused 0 (delta 0)
remote: error: insufficient permission for adding an object to repository database ./objects  remote: fatal: failed to write object

要解决这个问题,你必须记住操作系统的权限系统,因为在这种情况下你会受到它的限制。Tu更好地理解这个问题,继续检查你的git对象的文件夹(. git/对象)。你可能会看到类似这样的东西:

<your user_name>@<the machine name> objects]$ ls -la
total 200
drwxr-xr-x 25 <your user_name> <group_name> 2048 Feb 10 09:28 .
drwxr-xr-x  3 <his user_name> <group_name> 1024 Feb  3 15:06 ..
drwxr-xr-x  2 <his user_name> <group_name> 1024 Jan 31 13:39 02
drwxr-xr-x  2 <his user_name> <group_name> 1024 Feb  3 13:24 08

*请注意,这些文件的权限仅授予您的用户,没有人永远无法更改它…*

Level       u   g   o
Permission rwx r-x ---
Binary     111 101 000
Octal       7   5   0

解决问题

如果您拥有超级用户权限,您可以使用第二步自行更改所有权限,在任何其他情况下,您都需要询问所有拥有与其用户一起创建的对象的用户,使用以下命令来了解他们是谁:

$ ls -la | awk '{print $3}' | sort -u
<your user_name>
<his user_name>

现在,您和所有文件的所有者用户都必须更改这些文件的权限,执行以下操作:

$ chmod -R 774 .

之后,您将需要为新存储库添加一个等价于--共享=group的新属性,根据留档,这使存储库组可写,执行:

$ git config core.sharedRepository group

https://coderwall.com/p/8b3ksg

如果您使用与您计划在推送更改时使用的用户不同的用户运行git init,则很容易发生这种情况。

如果您盲目地遵循[1]上的说明,这种情况就会发生,因为您可能将git-user创建为root,然后立即转移到git init,而不会在两者之间更改user。

[1]http://git-scm.com/book/en/Git-on-the-Server-Setting-Up-the-Server

您需要对要推送到的目录具有足够的写入权限。

在我的情况下:Windows2008服务器

右键单击git repo目录或父目录。

属性>共享选项卡>高级共享>权限>确保用户具有适当的访问权限。

对于我的情况,没有任何建议有效。我在Windows上,这对我很有效:

  • 将远程存储库复制到另一个文件夹中
  • 共享文件夹并授予适当的权限。
  • 确保您可以从本地计算机访问该文件夹。
  • 将此存储库添加为本地存储库中的另一个远程存储库。(git remote add foo //SERVERNAME/path/to/copied/git
  • 推送到foo。git push foo master。它起作用了吗?太好了!现在删除不起作用的存储库并将其重命名为以前的任何名称。确保权限和共享属性保持不变。

解决了我… 只是这个:

sudo chmod 777 -R .git/objects

sudo chmod -R ug+w .;

基本上,.git/objects文件没有写入权限。上面的行授予目录中所有文件和文件夹的权限。

Linux,macOS:

cd .git/
sudo chown -R name:group *

其中name是您的用户名,group是您的用户名所属的组。

使用以下命令,像魔术一样工作

sudo chown -R "${USER:-$(id -un)}" .

完全按原样键入命令(在末尾加上额外的空格和一个点)

您还可能添加了具有相同别名的另一个本地存储库。例如,您现在有2个称为origin的本地文件夹,因此当您尝试推送时,远程存储库将不接受您的凭据。

重命名本地存储库别名,您可以点击此链接https://stackoverflow.com/a/26651835/2270348

也许你可以将一个你喜欢的本地存储库保留为origin,其他人将它们重命名为originanotherorigin。记住这些只是别名,你需要做的就是记住新的别名和它们各自的远程分支。

对我有用

sudo chmod -R g+rwX .

我在进入RStudio项目时得到了这个。我意识到我忘了做:

sudo rstudio

在程序启动时。事实上,我还有另一个bug,我需要做的是:

sudo rstudio --no-sandbox

我在Samba共享上的远程存储库遇到了这个问题;我成功地从这个远程拉取,但在推送时失败了。

错误的原因是我的~/.smbcredentials文件中的凭据不正确。

最简单的解决方案是:

从项目目录:

sudo chmod 777 -R .git/objects

在使用git很长时间没有问题之后,我今天遇到了这个问题。经过一番反思,我意识到我今天早些时候将我的umask022更改为其他东西。

其他人的所有答案都很有帮助,即对违规目录执行chmod。但根本原因是我的新umask,每当在.git/object/下创建新目录时,它总是会导致新的问题。所以,对我来说,长期的解决方案是将umask更改回022

我将添加我的两分钱作为在目录中发现具有特定所有权的文件的一种方式。

问题是由以root身份运行某些git命令引起的。 收到的消息是:

$ git commit -a -m "fix xxx"
error: insufficient permission for adding an object to repository database .git/objects
error: setup.sh: failed to insert into database

我首先查看了git config -l,然后我解决了:

find .git/ -exec stat --format="%G %n" {} + |grep root


chown -R $(id -un):$(id -gn) .git/objects/


git commit -a -m "fixed git objects ownership"

我在使用Vagrent运行远程开发开发机器时遇到此错误。上述解决方案都不起作用,因为所有文件都具有正确的权限。

我通过将config.vm.box = "hasicorp/bionic64"更改为config.vm.box = "bento/ubuntu-20.10"来修复它。

在我的情况下,解决方案只是再次git commit

问题自动消失了。

发生了什么事?我使用^C(Control-C)来中断写入错误的提交消息。(我从错误的剪贴板粘贴了错误的消息。)所以我假设该进程暂时冻结在后台,这暂时锁定了数据库。

只需将其复制并粘贴到您自己的终端中。

sudo chown -R "${USER:-$(id -un)}" .

我通过使用基于ssh://的URL而不是基于http://的URL解决了这个问题。

几天前我使用基于http://的URL克隆了存储库。在克隆和推送之间,我必须在我的帐户上启用2FA,然后将我的公钥添加到代码存储库中。

由于启用了2FA,http:// URL无法正常工作。

您需要在终端上复制并粘贴此命令:-

sudo chmod 777 -R .git/objects

确保以管理员身份打开命令行提示符。然后,确保项目文件不是只读的。

在windows中,您可以通过右键单击项目文件夹->单击“显示更多选项”->单击“属性”->取消选择“只读”->单击“应用”来检查这一点

输入图片描述

输入图片描述

输入图片描述

我遇到这个问题太多次了,但每次发生时,我都会尝试使用sudo命令推送或提交,输入密码后,我在没有sudo的情况下推送或提交 例如

sudo git commit -m "message"

然后输入我的密码后我再次

git commit -m "message"

我刚刚尝试了sudo git commit -m "XY",然后我用CTRL+C取消了它,然后用git commit -m "XY"再次尝试,然后它突然起作用了。

修复权限

我用这个来修复我的. git文件夹,@richard-hansen的答案缺少用户。

首先,您需要进入. git文件夹。

cd /path/to/repo/.git

然后执行这些命令。

sudo chown -R user:groupname .
sudo chmod -R g+rwX .
sudo find . -type d -exec chmod g+s '{}' +

这也将修复所有子模块。

这个问题还有一个解决方案,当您使用多个正在运行的docker容器并尝试更改和提交/推送某些内容时,可以复制该解决方案。

在我的情况下,当所有的容器都在那里时,我不能提交任何东西。但是一旦我杀了他们-我就能够毫无问题地提交。

我没有研究这种行为的原因,但我可以猜到你在本地更改的代码在docker容器中重用,因为它是从root用户运行的,因此它可以更改它使用的文件的一些权限-这可能会导致问题。