git hub의 원격 저장소의 파일들을 git pull을 하던중 기존의 내 파일들이 다 날아갔고 원격 저장소의 파일들로 덮어씌워졌다. 그래서 git log도 찾아보고 comitt명령도 reset해보았지만 결국에는 이틀전 커밋상태로 되돌아갔기 때문에 당일에 작업한 내용들이 다 날아가게 되었다. 또한 내가 작업한 파일들이 커밋을 분명했지만,,,? 파일 복구한다고 reset을 해버렸기때문에 커밋을 안한 경우나 마찬가지였다.
git reset --hard commit-id
이 명령어를 사용하더라도 복구는 쉽지 않은 상황이었다.
git fsck --lost-found
git add를 통해 stage는 되었었기 때문에 위 명령러로 파일(blob) 혹은 디렉토리(tree)의 해시값을 아래와 같이 출력할수 있었다.
사진상으론 몇개 안나오지만 실제론 600개가 출력되었다. 처음앤 git show명령어로 하나하나 다확인한 후 기존의 파일이나 새파일에 저장하는 방식으로 복구했지만 시간이 굉장히 오래걸리기도 하고 중복된 파일도 꽤 있어서 중간에 포기 하였다.
그래서 시간순으로 blob파일들을 출력해서 가장 최근 파일들만 추려서 내가 작업했던 기록들을 보기로 했다.
$ while read -r hash; do echo "$(git cat-file -t $hash)
$(git cat-file -s $hash) $(git show --pretty=format:'%ci' --quiet $hash) $hash";
done < blob_list.txt | sort
bash: warning: command substitution: ignored null byte in input
bash: warning: command substitution: ignored null byte in input
이 오류는 blob데이터 안에 널 바이트(null byte)가 포함되어 있음을 나타낸다.
$ while IFS= read -r hash || [[ -n "$hash" ]]; do
echo "$(git cat-file -t $hash) $(git cat-file -s $hash) $(git show --pretty=format:'%ci' --quiet $hash) $hash"
done < <(tr -d '\0' < blob_list.txt) | sort
bash: warning: command substitution: ignored null byte in input
bash: warning: command substitution: ignored null byte in input
bash: warning: command substitution: ignored null byte in input
그래서 tr -d '\0'을 통해서 null byte를 제외하고 출력해도 여전히 null관련 오류가 나타나고 null바이트를 없앤 새로운 파일을 만든 명령어를 통해서 다시 시간순 정렬 명령어를 해도 같은 오류가 나타나서 내가 내린 결론은 모든 파일이 유효하지 않은 해시가 기록된 파일이다.
아마 reset과 pull을 진행하면서 파일이 손상된 부분이 있다고 추측하였다.
find .git/objects -type f | while read object_file; do
# 파일 경로를 SHA-1 해시로 변환
sha1=$(basename $(dirname $object_file))$(basename $object_file)
# 파일 수정 시간 가져오기
timestamp=$(stat --format='%Y' "$object_file")
# 객체 정보와 타임스탬프 출력
echo "$timestamp $sha1 $object_file"
done | sort -n | while read timestamp sha1 object_file; do
# 사람이 읽을 수 있는 형식으로 변환
formatted_date=$(date -d @$timestamp "+%a %b %d %T %Y")
# 객체 타입 확인
object_type=$(git cat-file -t $sha1 2>/dev/null)
if [[ $object_type == "blob" ]]; then
echo "Object: $sha1" >> output.txt
echo "Timestamp: $formatted_date" >> output.txt
git cat-file -p $sha1 >> output.txt
fi
done
그래서 chat gpt를 통해서 위와같이 명령어를 입력해보았다. 이 명령어를 입력하면 해시코드를 git show한것을 output.txt파일에 저장하게 된다. 이파일을 notepad++로 열어준다(일반 메모장으로 열면 용량이 너무 커서인지 안열린다.)
그리고 열면
이런 파일이랑
이런파일이랑 나오는데
아마 이렇게 알아보기 힘든 것들은 파일이 손상되면서 이렇게 나타나게 되는 거 같다.
그래서 ctrl+f키를 눌러서 Timestamp: Tue Nov 19 18:15(내가 이 날 git pull하기전에 마지막으로 git add했던 시점)을 검색해주었다.
대략 시간대정도는 아니까 그걸 기준으로 검색하면 될 거 같다. 일이분씩 차이나는 파일들도 비교해가면서 어떤것이 내가 최종적으로 수정했던 파일인지는 스스로 판단해야한다.
각설하고, 이런 파일들을 얼추 맞춰가며 진행하던 프로젝트에 복붙하면서 95프로정도는 복구를 하였다. 5퍼센트는 내가 확인하면서 놓친부분이거나 파일자체가 날아간 부분이다.
앞으로는 git pull을 하기전에 꼭 따로 프로젝트 자체를 백업해두는 습관을 들여야겠다. 저번프로젝트에서도 이와 비슷한 상황이 있었는데 이번에 시간절약을 위해 안했는데, 시간 아낀다고 더 불필요하게 시간을 낭비해버렸으니 꼭 필요한 과정인거 같다. 또 백업해두면 여러모로 사용할 수 있는 곳이 많으니 백업 해둬야겠다.
오라클 자식키삭제시 부모키삭제트리거