Как мне выполнить поиск по коду потерянных коммитов?

#git

#git

Вопрос:

Я не спрашиваю, как восстановить известный коммит. Я спрашиваю, как выполнить поиск по содержимому файлов в коммит, которые появляются при выполнении таких команд, как

 git fsck --unreachable
git fsck --lost-found 
 

Я знаю имя файла, в котором был потерян код, и я могу быть уверен, что это было на прошлой неделе или 2. У меня даже есть довольно хорошая идея, где это находится в файле, но я понятия не имею, с какого коммита начинать. Как я могу это сделать, не сходя с ума?

Пока что самое большее, что я получил, это это, но было бы полезно, если бы он мог отфильтровывать нерелевантные файлы и коммиты и показывать измененный код:

 git log --graph --all --numstat --oneline --decorate --full-history --date-order --color $((git fsck --unreachable | awk '{ print $3 }'; git fsck --lost-found | awk '{ print $3 }') | grep -v 'Checking')
 

Ответ №1:

Начните с git fsck --lost-found варианта, чтобы он создавал «ссылки» на зависшие коммиты (подробности см. В git fsck документации). Это просто для того, чтобы упростить поиск списка идентификаторов хэшей коммитов и защитить их от сбора (я думаю, это защищает их) в случае, если Git запускает a gc --auto .

Теперь у вас .git/fsck/lost-found/commit есть каталог с большим количеством хэш-идентификаторов в нем. Это только идентификаторы хэша коммитов, поэтому дальнейшая фильтрация не требуется.

Затем для каждого «зависшего коммита» вы можете выполнить git grep или git log , используя необработанный хэш-идентификатор. Это не обязательно сохранит ваше здравомыслие, но, по крайней мере, у вас есть хэш-идентификаторы в файлах, а не в $(...) выходных данных оболочки. Я считаю, что это значительно упрощает работу с ними.

Ответ №2:

Вы можете отправлять несколько коммитов git grep , поэтому отправляйте недостижимые:

 mycommits=$(git fsck --unreachable | awk '$2=="commit" {print $3}')
git grep pattern $mycommits -- path/to/file
 

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

 printf %s\n $mycommits | git rev-list --stdin --no-walk --since=last.week