Git отклонение без переадресации

Мне кажется, что этот вопрос задавался много раз, но решение, как правило, "я удалил каталог и снова сделал свою работу со свежей проверкой". Я сделал фиксацию и нажал, но понял, что я указал неверный номер билета в сообщении фиксации. Поэтому я посмотрел на SO для быстрого решения и ввел в терминал следующее:

$ git reset --soft HEAD^
$ git commit -m "... correct message ..."

Единственная проблема - я получаю следующее сообщение об ошибке:

To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

Я использую модель git -flow и работаю над веткой разработки. Как я могу объединить все, чтобы сделать git счастливым снова?

Ответ 1

Сила git push:

git push origin +develop

Ответ 2

Если вы нажмете фиксацию на сервер, а затем перепишите эту фиксацию локально (с git reset, git rebase, git filter-branch или любые другие манипуляции с историей), а затем перезаписывать фиксацию на сервер, вы будете испортить кого-нибудь еще, кто потянул. Вот пример; скажем, что вы совершили A и нажали на сервер.

-*-*-A <-- master

-*-*-A <-- origin/master

Теперь вы решили переписать A так, как вы упомянули, сбросить и переустановить. Обратите внимание, что это оставляет свисающую фиксацию, A, которая в конечном итоге будет собрана мусором, поскольку она недоступна.

-*-*-A
    \
     A' <-- master

-*-*-A  <-- origin/master

Если кто-то еще, скажем, Фред, вытаскивает master с сервера, пока вы это делаете, у них будет ссылка на A, с которой они могут начать работать:

-*-*-A' <-- master

-*-*-A  <-- origin/master

-*-*-A-B <-- fred/master

Теперь, если бы вы смогли подтолкнуть свой A к исходному/мастеру, что создало бы не-быструю перемотку вперед, у него не было бы A в его истории. Поэтому, если Фред попытался снова вытащить его, ему вдруг пришлось бы слить и снова ввести A commit:

-*-*-A' <-- master

-*-*-A  <-- origin/master

-*-*-A-B-\ 
    \     * <-- fred/master
     A'--/

Если Фред замечает это, он может сделать переадресацию, что предотвратит повторное появление commit A. Но он должен был заметить это и не забудьте сделать это; и если у вас есть более одного человека, который вытащил A вниз, все они должны были бы переустановить, чтобы избежать получения дополнительной фиксации A в дереве.

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

git push -f

или

git push origin +master

Они оба будут игнорировать проверку на непереходное нажатие и обновить то, что на сервере, до вашей новой версии A, отказавшись от ревизии A, чтобы в конечном итоге собрать мусор.

Возможно, что принудительные нажатия полностью отключены с помощью опции receive.denyNonFastForwards config. Эта опция включена по умолчанию в общих репозиториях. В этом случае, если вы действительно хотите заставить толчок, лучшим вариантом является удаление ветки и ее повторное создание с помощью git push origin :master; git push origin master:master. Однако опция denyNonFastForwards включена по причине, описанной выше; в общем хранилище, это означает, что теперь каждый, кто его использует, должен обеспечить, чтобы они переходили на новую историю.

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

Ответ 3

Возможно, вам придется сделать git pull, который МОЖЕТ автоматизировать слияние вещей для вас. Затем вы можете совершить еще раз. Если у вас есть конфликты, он предложит вам их разрешить.

Имейте в виду, что вы должны указать, какую ветку вывести, если вы не обновили свой gitconfig, чтобы указать...

Например:

git pull origin develop:develop

Ответ 4

Я использовал EGit, и я тоже столкнулся с этой проблемой. Просто попробовал rebase текущую ветку и она работала.