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


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.


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


0

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

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

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


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) сработало.


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.