Есть ли способ отменить git push -f? - программирование
Подтвердить что ты не робот

Есть ли способ отменить git push -f?

Если я использую push -f для перекрытия последнего коммита, а именно A, в удаленном репозитории, а другие вытащили A до того, как я нажал.

В любом случае, чтобы отменить это, чтобы не вызвать проблемы для других?

Полезно ли push -f для оригинала " притворяться", что ничего не трогало?

или

Как git решает, отклоняется ли локальное репо от удаленного отслеживания?

4b9b3361

Ответ 1

Есть несколько способов узнать исходный HEAD перед нажатием (ORIG_HEAD, вероятно, не является одним из них):

Скроллинг терминала

Если вам повезет, что терминал открыт еще, будет некоторый вывод, когда был сделан push, который выглядит следующим образом:

...
To [email protected]:repo.git
 + abcdef0...1234567 HEAD -> branchname (forced update)

Здесь abcdef0 был предыдущим HEAD (ваш A) и 1234567 был тем, что вы заставили его вместо этого.

git reflog

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

Самая полезная команда здесь git reflog show remotes/origin/branchname. Это должно показать вам принудительное обновление (1234567) и предыдущий идентификатор фиксации (abcdef0) в качестве двух верхних строк.

Предыдущая рекомендация

Здесь может быть полезно несколько ссылок на фиксацию:

  • @{1} (или [email protected]{1}, если вы не находитесь на этой ветке) является предшествующим значением этой ссылки. Работает только в том случае, если вы не сделали никаких других коммитов в своем локальном филиале.
  • Аналогично, remotes/origin/[email protected]{1} будет предшествующим значением ref на пульте дистанционного управления. Работает только если кто-то еще не нажал на пульт.

Проверка, что у вас есть правильный идентификатор

Если вы хотите подтвердить, что идентификатор, который вы захватили из одного из приведенных выше методов, правильный, просто проверьте его:

git checkout abcdef0

и осмотритесь. Если git log выглядит знакомым (я также рекомендую tig для просмотра вашего репозитория, и вы даже можете запустить tig abcdef0, чтобы просмотреть журнал с данного коммита), то вы можете быть уверены, что вернетесь в нужное место.

Сброс в предыдущее состояние

Как только у вас есть предыдущий идентификатор фиксации, вы можете reset к этому и снова принудительно нажать:

git checkout branchname # if you're not on it already
git reset --hard abcdef0
git push -f

или просто:

git push -f origin abcdef0:branchname

Это приведет к восстановлению состояния ветки до состояния до принудительного нажатия.

Какое влияние?

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

git fetch
git checkout branchname # if you're not on it already
git reset --hard origin/branchname

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

git fetch
git checkout branchname # if you're not on it already
git rebase --onto origin/branchname 1234567

Вышеупомянутое означает, что "повторное воспроизведение всех коммитов после 1234567 (неправильная голова) поверх origin/branchname (правильная голова)."