Как отменить "git push -mirror"?
В проекте git/github я работаю над веткой. После нажатия он сказал следующее:
git push
To [email protected]:...
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '[email protected]:...'
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.
Я попытался исправить эту проблему, и после Google Google я придумал эту строку:
git push --mirror
Я выпустил следующую команду, и теперь кажется, что я удалил много ветвей с сервера.
Total 0 (delta 0), reused 0 (delta 0)
To [email protected]:...
- [deleted] develop
+ 797beee...bafbc50 master -> master (forced update)
- [deleted] milestone
- [deleted] robot
- [deleted] strategy
* [new branch] origin/HEAD -> origin/HEAD
* [new branch] origin/develop -> origin/develop
* [new branch] origin/master -> origin/master
* [new branch] origin/milestone -> origin/milestone
* [new branch] origin/robot -> origin/robot
* [new branch] origin/robot_simulator -> origin/robot_simulator
* [new branch] origin/strategy -> origin/strategy
* [new branch] origin/vision -> origin/vision
Можете ли вы рассказать мне, что произошло, и как я могу отменить изменения, которые я сделал? (в случае удаления этих ветвей)
Ответы
Ответ 1
Вы нажали на целевую цель по умолчанию, git @github.com. Это означает, что git @github.com был удаленным в вашем исходном репо.
Это означает, что refs, удаленные с сервера, все равно будут находиться на удаленном месте после нажатия. Не обновлять пульты (!).
Подтвердите это, выполнив
git branch -a
на стороне, с которой вы нажали (локальный).
Вероятно, будут показаны ссылки, удаленные с удаленного сервера.
[продолжение следует]
Вы можете сделать что-то вроде:
for-each-ref refs/remotes/origin | while read sha type name
do
git branch "rescue_$(basename "$name")" "$sha"
done
для восстановления ветвей локально. Они будут называться с префиксом rescue_
в качестве меры предосторожности (в случае, если вы получите смешные или противоречивые имена ссылок).
Замените origin
именем удаленного устройства
Тест script
Если вы хотите протестировать процедуру в контролируемой среде, вот мой подход сведен к минимальным шагам (выполняется в пустом каталоге, например, /tmp/work )
git init A; (cd A; touch test; git add test; git commit -m initial; git branch test1; git branch test2; git branch test3)
git clone A B
(cd B; git push --mirror origin; git branch -a)
cd A
git for-each-ref refs/remotes/origin | while read sha type name; do git branch "rescue_$(basename "$name")" "$sha"; done
git branch -a
Обратите внимание, как в этой версии я подключился к A
- это было бы вашим реестром github. Вы могли бы git clone --mirror [email protected]:... local_rescue
, чтобы получить подходящую локальную версию.
Я рекомендую вам поразвлечься с процедурой, прежде чем попробовать ее. Никогда не помешает создавать резервные копии ваших хранилищ на этом пути.
Ответ 2
Вы были в такой ситуации:
- x - A - B - C (origin/master)
\
D - E - F (master)
Вы хотели сделать одну из двух вещей, обе из которых описаны в документации, которую Git предложил вам прочитать:
-
Потяните, затем нажмите, давая вам следующее:
- x - A - B - C
\ \
D - E - F - M (master, origin/master)
-
Принудительное нажатие (git push --force
), дающее вам следующее:
- x - D - E - F (master, origin/master)
Вместо этого с git push --mirror
вы в основном сделали эквивалент принудительного нажатия всего, превратив удаленный репозиторий в зеркало вашего локального. Это означает, что, как и сообщалось, удаление всего на удаленном компьютере, которое не было в вашем репозитории.
Изменить: в ответе описывается, как восстановить. Если вы запустили git remote update
, который удалил бы удаленные ветки, которые он использует для восстановления, тогда может быть полезно следующее. В противном случае вы все настроены.
Лучше всего найти кого-то, кто клонировал из удаленного репозитория (или, если вам повезет, отдельный клон, который вы сделали), скажите им не вытащить/извлечь/удаленное обновление и следуйте инструкциям из этого репо.
В противном случае восстановление будет действительно сложным. Если вы недавно общались с какой-либо из отдаленных веток, возможно, в HEAD
reflog будут следы:
git reflog show
В противном случае, если удаленные ссылки ссылаются на коммиты, которые являются предками любых оставшихся ветвей, вы можете, возможно, быстро их воссоздать. Если они относятся к вещам, которые не являются предками оставшихся ветвей, вы можете найти оборванные коммиты:
git fsck
и, возможно, выясните, какие из них указали на них.