Как отменить "git push --mirror"?

в проекте git/github я работаю над веткой. После толчка он сказал следующее:--4-->

git push
To git@github.com:...
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:...'
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.

Я попытался исправить эту проблему и после Googleing я придумал эту строку:

git push --mirror

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

Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:...
 - [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

можете ли вы рассказать мне, что случилось и как я могу отменить изменения, которые я сделал? (в случае, если я удалил эти ветки)

2 ответов


вы нажали на цель push по умолчанию, git@github.com - ... Это значит, что git@github.com был удаленный в вас источник РЕПО.

это означает, что ссылки, удаленные с сервера, по-прежнему будут находиться в удаленном локально после нажатия. Не обновлять пульты (!).

проверьте это, выполнив

git branch -a

на стороне толкнул from (local).

он, вероятно, покажет ссылки, которые были удалены из удаленный сервер.

[Продолжение следует]

вы могли бы сделать что-то вроде:

for-each-ref refs/remotes/origin | while read sha type name
do 
    git branch "rescue_$(basename "$name")" "$sha"
done

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

заменить origin имя удаленного


тестовый скрипт

если вы хотите протестировать процедуру в контролируемой среде, вот мой подход сжато до минимальных шагов (выполняется в пустом каталоге, например, /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

обратите внимание, как в этой версии, я CD в A - который будет вашим репозиторием github. Ты мог бы!--6--> для того, чтобы получить соответствующую локальную версию этого.

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


вы оказались в такой ситуации:

- 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 вы в основном сделали эквивалент силы-толкая все, что делает пульт репозиторий в зеркало вашего локального. Это означает, как и сообщалось, удаление всего на удаленном компьютере, чего не было в вашем репозитории.

Edit: ответ sehe описывает, как восстановить. Если ты ... --26-->есть выполнить git remote update, который удалил бы удаленные ветви, которые он использует для восстановления, тогда может быть полезно следующее. В противном случае, все готово.

лучше всего найти кого-то другого, кто клонировал из удаленного репозитория (или если вы lucky, отдельный клон, который вы сделали), скажите им не тянуть / fetch / remote update, и следуйте инструкциям sehe из этого РЕПО.

в противном случае восстановление будет очень сложно. Если вы недавно взаимодействовали с любой из удаленных ветвей, возможно, в HEADС reflog:

git reflog show

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

git fsck

и, возможно, выяснить, какие из них имели ветви, указывающие на них.