Как отменить "git push --mirror"? - PullRequest
17 голосов
/ 08 февраля 2012

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

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.

Я пытался решить эту проблему, и после Google я получил следующую строку:

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 ]

12 голосов
/ 08 февраля 2012

Вы нажали на заданную по умолчанию цель push, git@github.com. Это означает, что git@github.com был удаленным в вашем репозитории.

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

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

git branch -a

на стороне, которую вы выдвинули из (местного).

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

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

Вы можете сделать что-то вроде:

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

Обратите внимание, что в этой версии я перехожу на A - который будет вашим репозиторием на github. Вы могли бы git clone --mirror git@github.com:... local_rescue, чтобы получить подходящую локальную версию этого.

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

3 голосов
/ 08 февраля 2012

Вы были в такой ситуации:

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

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

Лучше всего найти кого-то, кто клонировал из удаленного хранилища (или, если вам повезет, отдельный клон, который вы сделали), скажите им не извлекать / извлекать / удаленное обновление и следовать инструкциям Sehe из этого репозитория.

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

git reflog show

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

git fsck

и, возможно, выяснить, на какие из них были направлены ветки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...