Почему 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. Это ошибка?

  2. Теперь, когда я нахожусь в этом беспорядке, как я могу восстановиться?

(Примечание: я просто случайно наткнулся на это, используя вторичные рабочие деревья, поэтому я записываю это для потомков. Поэтому я выложу свой собственный ответ.)

1 ответ

Решение
  1. Да, это (очевидно) ошибка: тест Git "Это текущая ветвь" в коде пакета приема использует тест pre-множественных рабочих деревьев, который просто проверяет основное рабочее дерево HEAD, Необходимо изменить, чтобы проверить все рабочие деревья одинаково git worktree list делает.

    (Я работаю на двух системах, подключенных через VPN, где только на одной из них в настоящий момент запущен сервер, поэтому здесь я использую асимметричную модель выборки / отправки).

  2. К счастью, у меня не было незавершенной работы, поэтому восстановление было тривиальным: во вторичном рабочем дереве (на ветке pytest), просто беги:

    git reset --hard HEAD
    

    который очищает как индекс, так и рабочее дерево.

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

    git checkout -b tempbranch pytest@{1}
    

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

Другие вопросы по тегам