Сегодня передо мной встала довольно простая, но интересная задача: восстановить несколько файлов в репозитории Git, которые были удалены некоторое время назад в разных коммитах. Задача простая, потому что решение легко найти в соотвествующих ответах на Stack Overflow. Мне лишь осталось слегка адаптировать приведенные примеры команд для своих нужд.
Я не помнил точные названия файлов и уж тем более не знал хэши коммитов, в которых производилось удаление. Поэтому воспользовался сниппетом от пользователя Robert Munteanu, чтобы вывести историю удаленных файлов:
git log --diff-filter=D --summary
Отыскав необходимые файлы и коммиты, можно было бы воспользоваться простым git checkout
для восстановления, но список был весьма велик, так что пришлось набросать небольшой скрипт на Bash.
#!/bin/bash
set -o nounset
set -o errexit
declare -a files=(
"source/posts/2012-11-11-twitter/Untitled.png"
"source/posts/2013-06-08-wb/unnamed.png"
"source/posts/2012-10-13-lift/IMG_0020.png"
);
counter=0
while [ $counter -lt ${#files[@]} ]; do
file=${files[$counter]}
commit=$(git rev-list -n 1 HEAD -- "$file")
echo Restoring file: $file from commit: $commit
git checkout $commit^ "$file"
let counter+=1
done
В скрипте я объявляю массив с нужными мне файлами (в примере я сократил список). Далее в цикле проходимся по этому списку, при помощи команды git rev-list -n 1 HEAD -- "$file"
находим коммит, в котором последний раз использовался этот файл и при помощи git checkout $commit^ "$file"
восстанавливаем его из предыдущего коммита (для этого используется символ ^
).