Как правильно заставить 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 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 : это выполнит жесткий толчок в проверенном репозитории.