Git! [удаленное отклонение] мастер -> мастер (не удалось заблокировать) - PullRequest
0 голосов
/ 08 мая 2020

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

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

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

enter image description here

Прочие сведения:

$ 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

Ответы [ 2 ]

1 голос
/ 09 мая 2020

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

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

Помните, что имена веток и тегов являются c формами ссылок refs или . Каждый просто содержит 1 га sh ID. Имена тегов обычно содержат идентификатор ha sh либо тега объекта , который создает аннотированный тег, либо объекта фиксации, и после создания никогда не изменяются. Однако имена ветвей идентифицируют одну фиксацию в цепочке коммитов, и эта одна фиксация считается последней фиксацией, которая является частью этой ветки. (Могут быть последующие коммиты, но они не содержатся в этой ветке. Обратите внимание, что фиксация, идентифицированная именем ветки , может, тем не менее, содержаться в других ветвях.) это то, что эти значения регулярно меняются по мере роста ветвей. Так что пары должны быть обновлены.

Эти пары имя-значение, вероятно, должны храниться в какой-то транзакционной базе данных, но это не так. 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 ОС хоста должна (и предоставляет) предоставить для этого операцию «создать файл, но не выполнить, если он уже существует».

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

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

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


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

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

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

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

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

0 голосов
/ 08 мая 2020

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

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

  • удаленной ветки с именем master/xxx ( как здесь )
  • удаленная ветка с именем Master (разные заглавные буквы: проверьте также свой локальный .git/refs/heads на ту же проблему)
...