Гит! [удаленный отказ] master -> master (не удалось заблокировать)

Я не могу нажать на свой репозиторий git. git clone и git pull работают нормально, а git push не работает.

Я проверил другие ответы, такие как здесь, попробовал несколько способов, таких как git push origin master --force. Но ошибка остается той же.

Вот скриншот.

введите здесь описание изображения

Другие детали:

$ git show-ref refs/remotes/origin/master
8a205a0741f85fa309031a45f3613bf95a99148f refs/remotes/origin/master

$ git rev-parse --symbolic-full-name master
refs/heads/master

$ git rev-parse master
35ae39a241cd6bbfe7a9092f72b08279159e0056

$ git show-ref master
35ae39a241cd6bbfe7a9092f72b08279159e0056 refs/heads/master
8a205a0741f85fa309031a45f3613bf95a99148f refs/remotes/origin/master

Пожалуйста, помогите мне избавиться от этой ошибки.

ОБНОВИТЬ

$ git ls-remote
From https://xxx.git
8a205a0741f85fa309031a45f3613bf95a99148f        HEAD
8a205a0741f85fa309031a45f3613bf95a99148f        refs/heads/master
58feda6564bd52b9cce53da9862343aefd704202        refs/heads/new-0505
f24cd00e2f587689cdb92671769817c271bf0759        refs/heads/telestop
2a1afdf637a9108471eeddc755d49b74ef51e567        refs/meta/gitblit/reflog
8a205a0741f85fa309031a45f3613bf95a99148f        refs/remotes/origin/master

person Miron    schedule 08.05.2020    source источник
comment
не могли бы вы попробовать git push origin master:master? Честно говоря, я не могу объяснить, почему — я искал вашу ошибку, и это одно из наиболее распространенных предположений, но причины совершенно разные, и, насколько я могу судить, вы не попадаете ни в одну из них. Единственная общая черта заключается в том, что что-то не так с тем, что Git знает о ветках и реальных ветках. В одном случае он пытается нажать на имя ветки с неправильной заглавной буквой, в другой раз он должен был нажать на имя ветки a/b, хотя ветка a уже была. Или в локальном индексе git может быть просто мусор.   -  person VLAZ    schedule 08.05.2020
comment
@VLAZ Спасибо за указание. Но git push origin master:master выводит так же, как git push origin master.   -  person Miron    schedule 08.05.2020
comment
failed to lock ваш Git сообщает об ошибке, переданной от другого Git, и сбой блокировки там, по крайней мере в этом случае, не связан с тем, что вы можете исправить со своей стороны. Вам нужно будет попросить кого-нибудь, у кого есть доступ к серверу, зайти, посмотреть, что не так, и исправить это там.   -  person torek    schedule 08.05.2020
comment
Скорее всего, это вопрос разрешений, хотя детали частично зависят от того, какая ОС работает на сервере и как эта ОС настроена. В системах Windows есть проблемы с открытыми файлами; Системы Linux становятся непригодными для использования, когда вы включаете самые строгие параметры безопасности (SELinux).   -  person torek    schedule 08.05.2020
comment
@torek Ты прав. Я проверил ref/heads с сервера, на котором существовал master.lock файл. После того, как я удалил файл, git push удалось. Не могли бы вы опубликовать свою оценку в качестве ответа и объяснить возможные случаи, когда файл блокировки создается, пожалуйста?   -  person Miron    schedule 09.05.2020


Ответы (2)


Есть несколько возможных причин такого рода неудач. Согласно comment это оказалось быть устаревшим master.lock файлом на сервере. Достаточно удалить вручную.

Поскольку может быть более одной причины сбоя, не так уж полезно давать только один конкретный ответ. Однако мы можем обрисовать здесь общий процесс и то, что может пойти не так.

Помните, что имена ветвей и тегов — это особые формы refs или references. Каждый из них просто содержит один хэш-идентификатор. Имена тегов обычно содержат хэш-идентификатор либо объекта тега, который образует аннотированный тег, либо объекта фиксации, и после создания никогда не меняются. Однако имена веток идентифицируют одну фиксацию в цепочке коммитов, и эта фиксация считается последней фиксацией, являющейся частью этой ветки. (Могут быть последующие фиксации, но они не содержатся в этой ветке. Обратите внимание, что фиксация, идентифицированная именем ветки, может содержаться в других ветвях.) результатом этого является то, что эти значения регулярно меняются по мере роста ветвей. Таким образом, необходимо обновить пару ‹имя, значение›.

Эти пары имя-значение, вероятно, должны храниться в какой-то транзакционной базе данных, но это не так. В настоящее время Git (начиная со всех выпусков вплоть до сегодняшней версии 2.26.2 и, возможно, еще долго) хранит все эти ссылки в одном или обоих из двух мест: либо в одном плоском файле с именем packed-refs, либо в отдельных файлах, хранящихся в файловая система, например, refs/heads/master. Чтобы найти имя, Git сначала проверяет, существует ли отдельный файл. Если это так, файл будет иметь правильное значение. Если нет, Git проверяет, существует ли это имя в файле packed-refs, и если да, использует это значение. Если оба поиска не увенчались успехом, имя не существует.

Чтобы гарантировать, что любое обновление является атомарным — что никакая другая команда Git не может обновить имя, пока его обновляет одна команда Git, — Git использует тщательную последовательность создания .lock файлов. Например, чтобы обновить refs/heads/master, Git сначала создает refs/heads/master.lock.1 ОС хоста должна (и делает) предоставить для этого операцию «создать файл, но завершиться ошибкой, если он уже существует».

Здесь все может пойти не так. Предположим, например, что каталог (или папка, если вы предпочитаете этот термин) refs/heads/ отказывает в разрешении на создание нового файла идентификатору пользователя, который обрабатывает процесс git push. В этом случае создание master.lock завершится ошибкой типа "отказано в доступе".

В вашем конкретном случае файл master.lock уже существовал. Обычно такие файлы создаются, записываются, а затем удаляются или переименовываются. Однако в случае сбоя питания, сбоя системы или другого внезапного завершения программы Git система не остается в хорошем состоянии. В частности, файл .lock продолжает существовать.

В случае сбоев питания или сбоев системы можно войти и удалить устаревшие файлы .lock во время запуска системы. На практике это недостаточно распространено на большинстве серверов, чтобы с этим возиться — люди могут просто исправить свой Git-сервер вручную, как это сделали вы. Git-программы, как правило, не должны внезапно завершаться операционной системой, но некоторые системы используют «убийцы нехватки памяти» (OOM-killers), которые иногда могут вызывать такого рода проблемы.


1Создав соответствующий файл .lock, Git запишет новое значение в файл блокировки, а затем с помощью операции атомарного переименования превратит файл master.lock в файл с именем master, удалив все предыдущие файлы. . Это снимает блокировку и сохраняет новое значение таким образом, что любая другая команда Git, которой требуется это значение, увидит новое.

Git использует ту же технику для создания index.lock при обновлении своего индексного файла, но, поскольку записи индекса никогда не переносятся из одного Git в другой, любые сбои здесь всегда чисто локальны, а не во время git push. У этого метода есть еще одна особенность, заключающаяся в том, что «транзакцию» можно «откатить», просто удалив файл блокировки, а не переименовав файл блокировки в основное имя.

Помните термин ACID при работе с базами данных: атомарность, согласованность, изоляция, долговечность. Метод файла .lock обеспечивает атомарность и, если ОС делает правильные гарантии, согласованность и долговечность. Однако свойство изоляции полностью отсутствует: мы не можем обновлять одно поле базы данных отдельно. Вот почему Git использует отдельные файлы для каждой ссылки (за исключением случаев, когда это не так, через файл packed-refs, который поэтому фактически доступен только для чтения: только одна программа Git, git pack-refs, когда-либо обновляет его, используя собственную более сложную блокировку).

Отсутствие изоляции также может быть болезненным при работе с очень большим индексом. По этой причине Git может использовать режим «разделенного индекса», в котором некоторые записи (те, которые не менялись в последнее время) находятся во втором файле, а в основном .git/index файле находятся только «активно изменяющиеся» записи.

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

person torek    schedule 09.05.2020

Сначала проверьте, что возвращает git ls-remote.

Цель состоит в том, чтобы убедиться, что нет:

  • удаленная ветвь с именем master/xxx (как здесь)
  • удаленная ветвь с именем Master (другие заглавные буквы: проверьте также свою локальную .git/refs/heads для той же проблемы)
person VonC    schedule 08.05.2020
comment
Отлично, это то, что дало мое исследование. Так что, я не был дико от. Я был бы удивлен, если бы это произошло для OP, поскольку я бы предположил, что это новый репозиторий git, который имеет ветку master по умолчанию. Однако все, что я могу найти об этой ошибке, заставляет меня поверить, что это не так. - person VLAZ; 08.05.2020