Мерзавец, извлекающий "потерянные" коммиты

Краткая версия: возможно ли использовать 'git fetch' для получения коммитов из удаленного репо, которые не видны в журнале git (часть / под коммитом HEAD)

Более длинная версия: у меня есть репо (удаленная копия), которое выглядит так:

A - B - C - D(HEAD)
         \
          \-E

Удаленная версия достигла этого состояния, сделав коммит E, сбросив коммит C, затем сделав коммит D.

Локально у меня есть старый клон этого репо, который выглядит так:

A - B - C(HEAD)

Когда я получаю данные из удаленного репо, я получаю только коммит D, но я хотел бы иметь возможность сбросить --hard для коммита E в моем локальном репо.

2 ответа

Решение

Сначала немного предыстории, чтобы было яснее, что я имею в виду ниже: fetch Команда работает в двух частях, одна на вашем конце (вы запускаете git fetch) и один на удаленном (удаленный получает входящий запрос поверх http://, git://, ssh://или какой-то другой протокол и запускает что-то, обычно внутренний git upload-pack программа). Шаг закачки, который выполняется на удаленном компьютере, создает серию предложений в форме "У меня есть объект" (обычно это коммит или аннотированный тег) "с идентификатором ID типа type с именем name ".

Вы можете увидеть, что предложит пульт, запустив git ls-remote вместо git fetch, Это все еще работает upload-pack но вместо поиска того, что предлагается, он просто показывает (перечисляет) предложения.

Все, что вы видите здесь в списке предложений, - это то, что вы можете получить. Если он не появляется здесь, вы не можете получить его - или, по крайней мере, не через git fetch, Некоторые другие методы, в том числе git archive, может разрешить вам доступ к коммитам по их необработанным SHA-1, если вы их знаете.

Делать это в состоянии получить

Учитывая ваше описание, звучит так, как будто на пульте дистанционного управления включены повторные журналы (это обычный, не обнаженный репозиторий). совершить E Раньше был на какой-то ветви (и в HEAD), но был сброшен, так что он доступен только через две HEAD и филиал.

Обычно 1 upload-pack предложения HEAD плюс все ссылки в refs, Reflogs не в refs так upload-pack не предлагает их. Это означает, что если нет текущей ссылки, указывающей на ваш коммит E это не будет предложено. Чтобы получить предложение, войдите на удаленный сервер и создайте ссылку, указывающую на фиксацию. E и тогда будет.


1 Это несколько настраивается; увидеть git-namespaces и три hideRefs элементы конфигурации в git-config,

Сделать git fetch --all и вы получите все коммиты.

Оформить заказ нужного коммита и вот оно.

git fetch --all --prune
git checkout <SHA_1>
Другие вопросы по тегам