GIT : 삭제파일 복원

NtoZ·2023년 3월 17일
0

Git

목록 보기
4/5
post-thumbnail

Git 삭제파일 복원


문제 상황

  • 실수로 원격 저장소 특정 브랜치를 삭제하면서 해당 브랜치에 있던 파일 삭제.
  • 로컬/원격 브랜치 모두 해당 파일이 존재하지 않는 상황

문제 해결 과정

  1. git branch <임시 브랜치> : 작업을 진행할 임시 브랜치 생성

  2. git log --oneline 으로 복원하고싶은 커밋내역 보기 (commit 해시값 확인)

  3. git reset <commit 해시>

  4. git checkout . 으로 작업디렉토리의 모든 변경 사항 삭제
    (git checkout --<filename>으로 개별 파일에 대한 명령 사용 또는 삭제)
    ➡️나 같은 경우는 git log를 검색하고 reset <커밋해시>했을 때
    출력되는 기록이 D <복구하고싶은 파일>이었다.
    D는 delete의 플래그이므로, delete를 checkout으로 취소해준다면
    해당 파일이 복원되는 것이다. 복원하고 싶은 파일이 30여 개 정도 되었으므로, 일일이 파일명을 입력하지 않고 .(전체 내역 취소)을 입력했다.
    ⬆️(git reset <커밋해시>로 위 상태를 확인하고 git checkout . 입력!⬇️


  1. 이제는 로컬에서 복구된 파일을 확인할 수 있다. 따라서 git add , git commit -m "<커밋 메시지>", git push 하면 될 것이다.

  2. 그러나
    $ git push origin <원격저장소브랜치명>을 입력한 결과
    To https:<원격저장소 주소>
    ! [rejected] <로컬브랜치명> -> <원격브랜치명> (non-fast-forward)
    error: failed to push some refs to '<원격저장소 주소>'

    ➡️ 일반적으로 원격 저장소에 로컬 저장소에는 없는 커밋이력이 존재할 때 발생
    hint: Updates were rejected because the tip of your current branch is behind
    ➡️ 현재 (로컬)브랜치의 팁(가장 최근 커밋)이 뒤쳐져 업데이트가 거부되었다.
    이 경우 원격 브랜치의 새 커밋을 덮어쓰게 되므로 로컬 변경 사항을 원격 리포지토리로 푸시할 수 없다.문제를 해결하려면 먼저 원격 리포지토리에서 변경 사항을 가져와서 원격 브랜치의 새 커밋을 로컬 브랜치로 통합해야 한다. 이 작업을 수행하고 병합 충돌을 해결하면 로컬 브랜치가 원격 브랜치와 최신 상태가 되며 문제 없이 변경 사항을 푸시할 수 있다.
    ➡️ git fetchgit pull로 해결되지 않을 때는 별도의 병합과정이 필요!
    hint: its remote counterpart. Integrate the remote changes (e.g.
    hint: 'git pull ...') before pushing again.
    hint: See the 'Note about fast-forwards' in 'git push --help' for details.
    가 발생했다. git pull을 해도 git pull origin <원격브랜치> --allow-unrelated-histories를 해보아도 같은 상황이 발생했다.

  3. merge 문제를 해결하기 위해 mergetool 사용하기

  1. 다 해결 했으면 git push origin --delete <원격브랜치> : 원격브랜치 삭제하기로 임시 브랜치를 삭제해주면 된다.

  2. 마지막으로 branch를 git branch <로컬 저장소> 로 새로 만들고
    push 할 때 git push origin <새로 생성할 원격저장소>로 push해주면 로컬과 원격저장소가 만들어진다.


    참고 : git reset과 git revert 차이

    git reset및 둘 다 git revertGit 리포지토리에서 변경 사항을 실행 취소할 수 있는 Git 명령이지만 서로 다른 방식으로 작동합니다.

    git reset : 현재 분기(브랜치)를 지정된 커밋으로 이동하는 명령이며 스테이징 영역("인덱스"라고도 함) 및 작업 디렉터리를 수정하는 기능이 있습니다. 일반적으로 아직 원격 저장소로 푸시되지 않은 로컬 변경 사항을 실행 취소하는 데 사용됩니다. 를 실행하면 git reset커밋 기록이 변경되고 지정된 커밋 이후에 변경된 내용은 영구적으로 손실됩니다. 따라서 주의해서 사용해야 하며 항상 실행 결과를 이해하고 있는지 확인해야 합니다.

    반면에 git revert는 지정된 커밋에 의해 변경된 사항을 취소하는 새로운 커밋을 생성하는 명령입니다. 와 달리 커밋 기록을 수정하지 않고 이전 커밋에서 도입된 변경 사항을 효과적으로 실행 취소하는 새 커밋을 추가합니다 git reset. git revert즉, 다른 개발자가 작업 중인 기록을 변경하지 않으므로 공유 저장소에서 사용하는 것이 안전합니다. 그러나 다른 개발자가 되돌리려는 변경 사항과 충돌하는 변경 사항을 적용한 경우 충돌이 발생할 수 있습니다.

    요약하면 git reset는 분기 포인터를 이동하고 커밋 기록을 수정하는 동시에 git revert는 기록을 수정하지 않고 이전 커밋의 변경 사항을 실행 취소하는 새 커밋을 만드는 강력하지만 잠재적으로 위험한 명령입니다. 어느 것을 사용할지는 특정 상황과 원하는 결과에 따라 다릅니다.


    참고자료1 : 생활코딩 : 지옥에서 온 git
    참고자료2 : git reset과 git revert 차이 : git reset보다 git revert가 안전한 이유

  • 🤪제가 push에 실패했던 이유가 git reset을 사용했기 때문이었습니다...
    웬만하면 다음부터 git revert를 사용합시다.
profile
9에서 0으로, 백엔드 개발블로그

0개의 댓글