Как принудительно отправить сброс в удаленный репозиторий?

94

Наша удаленная главная ветка как-то испортилась. Текущий код разработки находится в основной ветке вместе с последними коммитами. Очевидно, что код разработки не готов для основной ветки.

Итак, в моем локальном репозитории я сбросил до последней версии тега git reset --hard (Tag). Основная ветка теперь верна в моем локальном репозитории. Теперь, когда я пытаюсь git push origin masterотправить изменения в удаленный репозиторий , я получаю сообщение об ошибке:

To (REMOTE GIT REPOSITORY LOCATION)
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

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

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To (REMOTE GIT REPOSITORY LOCATION)
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'

Я не могу использовать master, потому что он содержит код разработки, который не может быть на master.

Samwell
источник
3
Я думаю, это сообщение означает, что у вас нет прав на продвижение вперед без перемотки.
svick
3
Вы были правы, спасибо. В конфигурационном файле репозитория на удаленном компьютере denyNonFastforwards = true. Я изменил его на false, подтолкнул свои изменения, а затем снова изменил его на true. Еще раз спасибо всем за помощь.
Samwell
2
@samwell, пожалуйста, отметьте ответ svick как принятый
hultqvist
@samwell ответ svick сработал для вас или нет?
Сонго,
Для тех, кому нужны подробности о том, как отключить denyNonFastForwards, как это сделал Сэмвелл, дополнительные инструкции можно найти здесь: stackoverflow.com/a/43721579/2073804
ron190

Ответы:

152

Сообщение означает, что вам не разрешено выполнять нажатие без перемотки вперед.

Скорее всего, denyNonFastforwards = trueв вашем удаленном репозитории в config. Если вы измените это, git push --forceдолжно работать.

Чтобы изменить настройку, вам потребуется доступ к машине с удаленным репозиторием. Оттуда делай git config receive.denynonfastforwards false.

свик
источник
1
Вы можете сделать git configдля сервера? Или, возможно, вы использовали это метафорически. Чтобы поиграть с этими идеями, я создал тестовое репо в /opt/git(пространство моего сервера git), а затем изменил этот параметр в /opt/git/the_repo/the_repo.git/config. Но после того, как сделал, git push --force origin SHA:branchработал по мере необходимости.
HankCa
4
В сообщении об ошибке будет строка, начинающаяся с «ошибка: не удалось отправить некоторые ссылки в <ваш репозиторий>», где <ваш репозиторий> - это путь, заканчивающийся на .git, который представляет собой каталог, содержащий файл с именем «config». Этот файл «конфигурация», где вы можете установить denyNonFastforwards = False
наждак
1
Комментарий @ emery ценен. Иногда для папки на сервере указывается что-то вроде /srv/git/repo.git. Это конфигурация, в которой установлен denyNonFastForwards, а не папка приложения.
Элайджа Линн
1
@hsalimi Если у вас нет доступа к серверу, вам нужно связаться с администратором сервера и попросить его временно отключить его, чтобы вы могли принудительно нажать, а затем снова включить. Однако маловероятно, что большинство из них в состоянии сделать это. Это может быть более распространено во внутренней среде с вашей собственной командой хостинга.
Элайджа Линн
1
Сначала это расстраивает, но прелесть этого заключается в том, что пульт по умолчанию полностью защищен, и если вы, как разработчик, намеренно и правильно выполняете переустановки, вы можете переопределить эту конфигурацию, чтобы разрешить опасное поведение. Ребазинг - это то, что каждый пользователь git должен знать, как делать, и знать, когда этого делать нельзя. doc1 doc2
moodboom 01
15

Пульт дистанционного управления не допускает перемотки вперед.

Ваш лучший вариант - выполнить git revertвсе коммиты, которых не должно быть, и будьте осторожнее в будущем.

git revert [commit]создаст новый коммит, который отменяет все, что было [commit]сделано.

рико
источник
Это были некоторые настройки в удаленном репозитории, которые блокировали все изменения без перемотки вперед.
samwell
Если вы сделаете это и вам нужно повторно применить коммиты, история не будет удалена при возврате, только изменится код, и вы не сможете выбрать коммиты или слить их
mtpultz
12

Действия по постоянному включению принудительного толчка в следующем стиле

git push -f myrepo my-branch

Отредактируйте файл с именем «config» в папке, заканчивающейся на «.git», в удаленном репозитории.

В выводе командной строки git после неудачного нажатия найдите строку, которая говорит что-то вроде:

error: failed to push some refs to 'ssh://user@some-remote-server.mycompany.com/srv/git/myrepo.git

затем

ssh user@some-remote-server.mycompany.com
cd /srv/git/myrepo.git
vi config

Установите для denyNonFastforwards значение false

В "config" установите

[receive]
        denyNonFastforwards = false

Теперь вы можете нажать с локального компьютера с помощью -f

git push -f myrepo my-branch
Эмери
источник
Как это сделать без доступа к SSH для чистого репозитория git?
Владимир Вуканац
Может быть, использовать команду git revert, как предлагает Ричо? Если вы сначала сделаете резервную копию текущего состояния репо, вы все равно можете объединить свой код в дальнейшем.
emery
git revertэто довольно сложно, когда у вас есть слияния. Чтобы быть более сложным, в моем случае есть 3 слияния, одно из которых связано с очень старым ~ 20 коммитом, отличным от разработки, второе - это своего рода слияние от мастера - уродливо, как черт.
Владимир Вуканац
1
Возможно, решение состоит в том, чтобы сбросить до желаемого состояния, создать резервную копию (тайник), снова извлечь и применить резервную копию (тайник).
Владимир Вуканац
1
mrW, вы все еще можете объединить базу кода, которую хотите, поверх восстановленной / извлеченной базы кода
emery
11

Попробуйте использовать -fфлаг и поставить его после имени удаленной ветки.

git push origin master -f

Крис Ледет
источник
1
Нет, это тоже не сработало. Я тоже попробовал git push -f origin masterи результат тот же. Оба раза я пробовал, но получил вторую версию сообщения об ошибке.
Samwell
2

Вам не разрешено делать git push без перемотки вперед.

  1. Если удаленным является GitHub, перейдите в https://github.com/$USER/$REPO/settings/branchesсоответствующую ветку и снимите защиту.

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

    Для этого вы должны быть администратором репо.

  2. Если пульт - ваш собственный сервер git, запустите git config receive.denynonfastforwards falseего.

филиф
источник
Имейте в виду, что для экземпляров Git Hub Enterprise отправка в ветку по умолчанию (обычно «главную») может быть отключена на уровне экземпляра. Это означает, что даже если «мастер» не защищен, и даже если вы являетесь администратором сайта, вы не сможете выполнять принудительное нажатие на ветку по умолчанию. Предполагая, что у вас есть разрешения, вы можете временно обойти это, переключив ветку по умолчанию на что-то другое, сделав принудительное нажатие, а затем переключившись обратно.
Кристофер Хантер
2

Лучший способ обойти это - удалить удаленную ветку и повторно отправить ее:

git push origin master --delete
git push origin master
Данило Соуза Морайнш
источник
0

Проблема возникает, поскольку текущая ветвь не настроена должным образом для PULL . Сначала проверьте, правильно ли настроена восходящая ветвь для вытягивания, используя - git remote show origin. Вы можете найти его в разделе - Локальные ветви , настроенные для «мерзавца тянуть»: . Если нет, настройте его, используя:

git config branch.MYBRANCH.merge refs/heads/MYBRANCH

Дайте подходящее название ветки для заполнителя - MYBRANCH

Sudheesh.MS
источник
0

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

Думаю, в вашем случае этот способ не сработает, но может быть полезен кому-то другому

перейдите в исходную папку, затем запустите команды: обратите внимание, что https://github.com/*.gitэто ваша ссылка удаленного репо

git init
git remote add origin https://github.com/*.git
git add .
git commit -m "initial commit"
git push origin master -f
git push --set-upstream origin master

**Note: this will clear all your git history on your master branch**

Халед АбуШкар
источник
0

Для меня подсказка @svick указала в правильном направлении. Поскольку git-сервер, который я хотел изменить, на самом деле является моим ящиком, я вошел в него и сделал, git config --global receive.denynonfastforwards falseчтобы изменить все репозитории, чтобы принять принудительное нажатие не-ff. Не вышло из коробки. Я обнаружил, что в конфиге он уже был receive.denynonfastforwards=trueустановлен, и его нельзя стереть с помощью git config --global --unset receive.denynonfastforwards. Однако редактирование в репо вручную ( vi config) сработало.

Jglathe
источник
0

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

дашра хадка
источник