Как правильно заставить Git push?

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

Теперь мне пришлось что-то менять в удаленном репо. Затем я изменил что-то в своем локальном репо. Я понял, что смена удаленного репо не нужна. Поэтому я пытался git push из моего локального репо в мое удаленное репо, но я получил ошибку вроде:

Чтобы предотвратить потерю истории, обновления без ускоренной пересылки были отклонены. Объедините удаленные изменения перед повторным нажатием. См. Раздел "Примечание о быстрой перемотке" git push --help для деталей.

Я думал, что, вероятно,

git push --force

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

Как я уже упоминал в комментариях к одному из ответов:

[Я] попытался форсировать, но когда возвращаюсь на главный сервер, чтобы сохранить изменения, я получаю устаревшую постановку. Таким образом, когда я фиксирую репозитории, они не совпадают. И когда я пытаюсь использовать git push снова, я получаю ту же ошибку.

Как я могу исправить эту проблему?

13 ответов

Решение

Просто делать:

git push origin <your_branch_name> --force

или если у вас есть определенный репо:

git push https://git.... --force

Это удалит ваш предыдущий коммит (ы) и подтолкнет ваш текущий.

Возможно, это не совсем правильно, но если кто-то наткнется на эту страницу, подумав, что, возможно, им нужно простое решение...

Короткий флаг

Также обратите внимание, что -f коротка для --force, так

git push origin <your_branch_name> -f

тоже будет работать.

И если push --force не работает, вы можете сделать push --delete, Посмотрите на 2-ую строку в этом случае:

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git push origin master --delete  # do a very very bad bad thing
git push origin master  # regular push

Но будьте осторожны...

Никогда не возвращайся к публичной истории!

Другими словами:

  • Никогдаforceнажмите на публичный репозиторий.
  • Не делай этого или что-нибудь, что может сломать кого-тоpull,
  • Никогдаresetили жеrewriteисторию в репо кто-то уже мог вытащить.

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

Сделайте возврат вместо этого.

Ивсегда будьте осторожны с тем, что вы подталкиваете к публичному репо. Откат:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git push origin master  # regular push

В сущности,оба заголовка источника (от возврата и сброса зла) будут содержать одинаковые файлы.


изменить, чтобы добавить обновленную информацию и больше аргументов вокругpush --force

Подумайте о толкании силой с арендой, а не о толчке, но все же предпочитайте возврат

Другая проблемаpush --forceМожет принести, когда кто-то что-то толкает, прежде чем вы, но после того, как вы уже получили. Если вы нажмете форсированную версию сейчас, вызамените работу других.

git push --force-with-leaseпредставленный в git 1.8.5( благодаря комментарию @VonC к этому вопросу) пытается решить эту конкретную проблему. По сути, это приведет к ошибке и не будет выдвигаться, если пульт был изменен с момента последней загрузки.

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

И так как мы говорим оgit --pushэкземпляры...

Почему кто-то хочет заставить толкать?

linquize привел хороший пример толчка в комментариях:конфиденциальные данные. Вы ошибочно просочились данные, которые не должны быть отправлены. Если вы достаточно быстры, вы можете "исправить"*это путем принудительного толчка сверху.

* Данные по-прежнему будут находиться на удаленном компьютере, если вы не выполните сбор мусора или не очистите его каким- либо образом. Существует также очевидный потенциал для его распространения другими, кто уже получил его, но вы поняли идею.

Если я нахожусь в моей локальной ветви A, и я хочу принудительно передать локальную ветвь B к исходной ветви C I, можно использовать следующий синтаксис:

git push --force origin B:C

Используйте следующую команду:

git push -f origin master

Прежде всего, я бы не стал вносить никаких изменений непосредственно в "основной" репо. Если вы действительно хотите иметь "основное" репо, то вам следует только подтолкнуть его, а не менять его напрямую.

Что касается ошибки, которую вы получаете, пытались ли вы git pull из вашего местного репо, а затем git push в основной репо? То, что вы сейчас делаете (если я хорошо это понял), это форсирование, а затем потеря ваших изменений в "основном" репо. Сначала вы должны объединить изменения локально.

сделает работу, хотя это более безопасная команда

перезаписывает удаленную ветвь, атолько перезаписывает удаленную ветку, если ваша локальная копия знает обо всех коммитах в удаленной ветке. Эта разница значительно усложняет уничтожение чужих изменений в проекте.

Я действительно рекомендую:

  • толкать только в основной репо

  • убедитесь, что основное репо является чистым репо, чтобы никогда не возникало проблем с рабочим деревом основного репо, не синхронизированным с его .git база. Смотрите " Как перенести локальный репозиторий git на другой компьютер?"

  • Если вам нужно внести изменения в основной репозиторий (клон), клонируйте его (на главном сервере), внесите изменения и вернитесь к нему.

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

У меня был тот же вопрос, но я наконец понял его. Скорее всего, вам нужно выполнить следующие две команды git (заменив хэш номером редакции git commit):

git checkout <hash>
git push -f HEAD:master

С использованием--force-with-leaseможет быть лучший вариант:

      git push <remote> <branch> --force-with-lease

Это гарантирует, что никто не обновил ветку до того, как вы изменили ее, поэтому вы не перезапишете их изменения.

если вы аутентифицируетесь с помощью токена доступа Github, попробуйте следующее:

  • git удаленный источник set-url https: // YourTokenNum@github.com / UserName / ProjectName

  • git push --force --set-upstream origin master

Это было наше решение для замены master в корпоративном репозитории gitHub при сохранении истории.

push -f мастер на корпоративных репозиториях часто отключается, чтобы поддерживать историю ветки. Это решение сработало для нас.

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master

git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

подтолкнуть свою ветку к desiredOrigin и создать пиар

Моя проблема была - я сделал:

      git checkout arbitrary_commit
git push origin master --force

что было не правильно делать. Вместо этого мне пришлось:

      git reset HEAD~3
git push origin master --force

Примечание: число 3это просто пример. Вы должны поставить свой собственный номер.

git push -f origin : это выполнит жесткий толчок в проверенном репозитории.

Другие вопросы по тегам