Почему Git позволяет переместиться в извлеченную ветку в добавленном рабочем дереве? Как мне восстановиться?
Git обычно отказывается от нажатия на (одну) проверенную в данный момент ветку обычной, не--bare
репозиторий:
$ git push upstream master Counting objects: 1, done. Writing objects: 100% (1/1), 188 bytes | 0 bytes/s, done. Total 1 (delta 0), reused 0 (delta 0) remote: error: refusing to update checked out branch: refs/heads/master remote: error: By default, updating the current branch in a non-bare repository remote: error: is denied, because ...
Это правильное поведение. Смотрите Git push error '[удаленный отклоненный] master -> master (ветвь в настоящее время извлечена)'.
Тем не менее, в том же самом апстриме у меня есть добавленное рабочее дерево с другой веткой. Непосредственно перед вышеприведенной демонстрацией ошибок я запустил:
$ git push upstream pytest
и это удалось, когда явно не должно быть, по той же причине master
терпит неудачу здесь. Особенно, receive.denyCurrentBranch
действительно установлен, чтобы отрицать текущие ветви.
В этой восходящей системе, git worktree list
говорит:
$ git worktree list
<path1> 9febb4c [master]
<path2> 406bef8 [pytest]
который показывает, что по крайней мере часть Git знает, что он проверен. Но тогда это все равно позволило толчок, что приводит к двум вопросам:
Это ошибка?
Теперь, когда я нахожусь в этом беспорядке, как я могу восстановиться?
(Примечание: я просто случайно наткнулся на это, используя вторичные рабочие деревья, поэтому я записываю это для потомков. Поэтому я выложу свой собственный ответ.)
1 ответ
Да, это (очевидно) ошибка: тест Git "Это текущая ветвь" в коде пакета приема использует тест pre-множественных рабочих деревьев, который просто проверяет основное рабочее дерево
HEAD
, Необходимо изменить, чтобы проверить все рабочие деревья одинаковоgit worktree list
делает.(Я работаю на двух системах, подключенных через VPN, где только на одной из них в настоящий момент запущен сервер, поэтому здесь я использую асимметричную модель выборки / отправки).
К счастью, у меня не было незавершенной работы, поэтому восстановление было тривиальным: во вторичном рабочем дереве (на ветке
pytest
), просто беги:git reset --hard HEAD
который очищает как индекс, так и рабочее дерево.
Если бы я не был, однако, самый простой трюк состоял бы в том, чтобы заставить новую ветвь существовать с предыдущим значением ветви, а затем проверить эту ветвь. Это можно сделать за один шаг:
git checkout -b tempbranch pytest@{1}
Рабочее дерево теперь будет на другом (предварительно
push
) ветвь, где временная работа теперь может быть совершена или спрятана или перебазирована, или как угодно, и обрабатываться обычным способом.