Git push не может записать в объектный файл — доступ запрещен

Git push не может записать в объектный файл — доступ запрещен

Я нахожусь на клонированном репозитории и пытаюсь отправить изменения в свою удаленную ветку. Коммит работает нормально, однако всякий раз, когда я пытаюсь отправить изменения, я получаю это:

error: unable to write file ./objects/foo/bar: Permission denied

Я являюсь владельцем всех файлов в локальном репозитории, и обычно push-уведомления проходят нормально, однако через некоторое время возникает эта ошибка, и я не могу выполнить push-уведомления.

Единственное решение проблемы — вернуться к последнему коммиту в origin и попытаться найти файл, который предположительно вызывает проблемы.

Затем я нажимаю на новый файл и вставляю содержимое из старого "сломанного" файла. Иногда это тоже не помогает, и очевидно, что это не управляемый обходной путь.

решение1

Я столкнулся с этой проблемой и нашел этот вопрос. Я прочитал совет, размещенный наhttps://www.thegeekstuff.com/2017/05/git-push-error/и подведу итоги того, что решило проблему (для меня).

Исправление заключалось в настройке хоста, содержащего GIT REPO, так, чтобы он содержал общую группу, в которую были добавлены все пользователи git. Например, /etc/group

git:x:4001:user1,user2

Затем на хосте, содержащем репозиторий git, выполните следующие команды:

cd /local/git-repos/repo1.git
sudo chgrp -R git objects
sudo chmod -R g+rws objects

Для меня это решило проблему. В указанной статье объясняется больше о настройке репозитория как общего репозитория, но я (пока) этого не сделал.

git config core.sharedRepository group

Почему это может произойти? Читайте дальше, если вам интересно.

Почему это происходит?

Для меня это произошло, когда я настроил частный git-репозиторий, которым я (user1) поделился с некоторыми коллегами. Репозиторий был на моем хосте (скажем, host1), и user2@host2 также его использовал.

Ниже приведены шаги, которые я использовал для настройки, и в соответствующем месте я объясню, где возникла проблема.

  1. Меня зовут user1@host1, и я создаю чистый репозиторий git с помощью:

    mkdir /local/git-repos
    cd /local/git-repos
    git init --bare repo1.git
    
  2. Я настраиваю файл ~/.ssh/config так, чтобы имя, используемое для репозитория git, было логическим именем. Это делается для того, чтобы, если я перенесу свой ящик на другую машину, мне нужно было бы просто обновить псевдоним хоста на новое имя компьютера.

    Файл:$HOME/.ssh/config

    Host mygithost
        HostName host1
    
  3. Затем я клонирую репозиторий с помощью

    cd $HOME
    git clone mygithost:/local/git-repos/repo1.git
    cd repo1
    # Add files and use normal git commands
    git add -u .
    git commit
    git push
    

    Обновления отправляются в репозиторий git на компьютере.

  4. Настройте пользователя user2 так, чтобы он мог получить доступ к этому же репозиторию GIT.

    • Вам нужно будет настроить файл $HOME/.ssh/config так же, как это было сделано для user1.
    • Убедитесь, что пользователь имеет доступ по протоколу SSH к хосту host1 от своего имени.
    ssh user2@mygithost echo it worked
    cd $HOME
    git clone mygithost:/local/git-repos/repo1.git
    

    На этом этапе оба пользователя, user1 и user2, могут получить доступ к общему репозиторию GIT.

    ЕслиОБАпользователи делают коммиты, то объекты git REPO будут иметь некоторые файлы, принадлежащие , user1и некоторые файлы, принадлежащие user2. Проблема в том, что позже при user1попытке отправить файлы на GIT HOST objectсозданные файлы и каталоги могут принадлежать , user2поэтому возникает следующая ошибка.

    error: insufficient permission for adding an object to repository database ./objects
    fatal: failed to write object
    error: unpack failed: unpack-objects abnormal exit
     ! [remote rejected] master -> master (n/a (unpacker error))
    error: failed to push some refs to [email protected]:/home/git/myproj
    
    

    Решение состоит в настройке репозитория git bare таким образом, чтобы любой пользователь мог читать/записывать файлы, созданные любым другим пользователем. Это делается на следующем шаге с использованием UNIX GROUPразрешений.

  5. Настройте REPO так, чтобы разные пользователи могли получить доступ к репозиторию git.

    • Создайте ГРУППУ, в которую смогут входить все пользователи

      sudo vi /etc/group
      git:x:4001:user1,user2
      
    • Измените все файлы так, чтобы они правильно располагались в только что созданной группе.

      cd /local/git-repos/repo1.git
      sudo chgrp -R git objects
      sudo chmod -R g+rws objects
      

    Используйте любую общую группу, созданную выше ( gitв этом примере).

ПРИМЕЧАНИЕ: Бит group-suid важен, поскольку он заставляет будущие файлы/каталоги, которые будут созданы, сохранять те же настройки, что и родительский каталог.https://www.redhat.com/sysadmin/suid-sgid-sticky-bit, там говорится:

Если установлено для каталога, то для всех файлов, созданных в каталоге, будет установлена ​​группа владения, соответствующая владельцу каталога.

Краткое содержание

Эта ошибка обычно не должна возникать в любом нормально размещенном GIT REPO. Но она может возникнуть в описанной ситуации, когда частный (на основе файлов) репозиторий настроен и совместно используется несколькими пользователями.

Связанный контент