Для решения был написан скрипт на python.
# -*- encoding: utf-8 -*-
import git
import re
from os import path, mkdir
from subprocess import Popen, PIPE
def find_that_hash(source_hashes, aim):
# выделить из списка "source_hashes" те записи, в информации о которых есть вхождение строки aim
found_hashes = []
for tmp_hash in source_hashes:
infa = repo.git.cat_file('-p', tmp_hash)
if infa.find(aim) != -1:
found_hashes.append(tmp_hash)
return found_hashes
def find_hash_in_info(source_hash, aim):
# выделить из информации о хэше source_hash строки, в которых есть вхождение строки aim и разбить эти строки на слова
found_hashes = []
for info_string in repo.git.cat_file('-p', source_hash).split('\n'):
if info_string.find(aim) == -1:
continue
else:
tmp1 = re.split('[\t]+', info_string)
tmp2 = re.split('[ ]+', tmp1[0])
tmp2.append(tmp1[1])
found_hashes.append(tmp2)
return found_hashes
#===========================================================================
project_path = '/home/user/project/'
secure_files_path = project_path + 'media/secure-files/'
repo = git.Repo(project_path)
unreachable = repo.git.fsck('--unreachable')
lost_found = repo.git.fsck('--lost-found')
strings = [s for s in unreachable.split('\n')] + [s for s in lost_found.split('\n')]
tree_hashes = [s.split()[2] for s in filter(lambda x: ' tree ' in x, strings)]
commit_hashes = [s.split()[2] for s in filter(lambda x: ' commit ' in x, strings)]
our_docs_hashes = find_that_hash(tree_hashes, 'secure-files')
if not our_docs_hashes:
print 'Hash of "secure-files" dir not found'
else:
if not path.exists(secure_files_path):
mkdir(secure_files_path)
for our_docs_hash in our_docs_hashes:
secure_dir_hash_info = find_hash_in_info(our_docs_hash, 'secure-files')[0]
for sub_dir_info in find_hash_in_info(secure_dir_hash_info[2], 'tree'):
current_path = secure_files_path + sub_dir_info[3] + '/'
if not path.exists(current_path):
mkdir(current_path)
for file_info in find_hash_in_info(sub_dir_info[2], 'blob'):
rubbish = "printf '%b\n'"
fn, _ = Popen("%s '%s'" % (rubbish, file_info[3]), shell=True, stdout=PIPE).communicate()
file_name = '%s%s' % (current_path, fn[1:len(fn)-2])
if not path.exists(file_name) and fn[1:len(fn)-2] != '':
f = open(file_name, 'w')
f.write(repo.git.show(file_info[2]))
f.close()
print 'Restored: %s' % (file_name)