Answer the question
In order to leave comments, you need to log in
How to get back lost files in git stash clear?
On the bench where git is deployed, a combination of commands was executed:
git add .
git stash
git stash clear
As a result, all files that were not in the repository were deleted. Even those that were added by users in the process of using the stand.
To search for lost files, the following command was executed:
git fsck --unreachable
Among the results obtained, a tree (tree) was found that contained the folder where the searched files were. On further travel through the tree, the files were found.
How now to revert these files if they were not included in any commit?
Answer the question
In order to leave comments, you need to log in
For the solution, a python script was written.
# -*- 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)
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question