본문 바로가기

개발관련 기술

GIT 복구, 복원 또는 되돌리는 작업 정리

흐미 ...

프로그램 소스파일 캐릭터셋 잘못 지정해서 commit & push 하는 바람에 복구하는라 애 먹었다.

비상발생시 처리는 잊은지 오래된 이야긴데....

어쨌든 살리는 방법 시험해서 정리한 다음 로깅해 둔다.

기억력이 현저히 떨어져 가는 나를 포함해서 잘 모르시는 분이 보면 도움이 될꺼다.

혹시 잘 아시는 분 있으면 가르침을 바란다.

이거 하느라고도 애썼다 ...

 

 

---- 작업기록 그래프로 본것 ---

목표: 커밋 아이디가 5b9153f 인 녀석을 그 전인 0b062be 로 복원하려는 것이다

-----------------------
/* GIT 복원시험 */
-----------------------
1. HEAD 변경이력 확인
   {
      $ git reflog
      5b9153f (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: commit: 다시 4: git revert 를 위해 버려야할 수정 잘못된 수정입니다
      0b062be HEAD@{1}: commit: 다시 3: git revert 복구하면 이 메시지가 보여야 합니다.
      33b3c53 HEAD@{2}: commit (merge): 서버와 상태가 달라서 머지한 후
      5ff9fc6 HEAD@{3}: commit: 다시 2: git revert 복구하면 이 메시지가 보여야 합니다.
   }

2. 복구할 HEAD 선택 (commit id : 0b062be)
   : git reset {--soft | --hard | --mixed} {commit id | HEAD~숫자}
   {
      $ git reset --hard 0b062be
      HEAD is now at 0b062be 다시 3: git revert 복구하면 이 메시지가 보여야 합니다.

      $ git reflog
      0b062be (HEAD -> master) HEAD@{0}: reset: moving to 0b062be
      5b9153f (origin/master, origin/HEAD) HEAD@{1}: commit: 다시 4: git revert 를 위해 버려야할 수정 잘못된 수정입니다
      0b062be (HEAD -> master) HEAD@{2}: commit: 다시 3: git revert 복구하면 이 메시지가 보여야 합니다.
      33b3c53 HEAD@{3}: commit (merge): 서버와 상태가 달라서 머지한 후
      5ff9fc6 HEAD@{4}: commit: 다시 2: git revert 복구하면 이 메시지가 보여야 합니다.
   }

3. 상태 확인
   {
       파일을 확인하니 { 복구할 과거내용으로 } 복구 되었다.
       잘 되었네...
   }

4. 복구한다 
   실제 처리내역을 확인해 보니 복구라기 보다는 브랜치를 만든 것 같다
   reset 명령으로 이미 파일들은 원상 복구 되었으며 revert 명령으로 새로운 브랜치(5d65f1e)가 생겼다.
   revert 실행결과에 "1 file changed, 1 insertion(+), 1 deletion(-)" 이런메시지 추가 확인됨
   이후 복구내역을 리모트로 git push 하니 리모트에는 master (5b9153f ) 가 존재하므로 pull 하여 싱크하란다
   git pull 하니 자동머지가 돌다가 conflict 떨어지고 
   서로 다른 부분을 vscode (mergetool 로 등록됨) 화면으로 보여준다
   vscode 에서 변경 된 부분 중 한 곳을 선택하여 저장한 다음 git add, git commit, git push 를 순차적으로 하니 
   master 와 revert로 생성된 브랜치가 합하여 하나의 마스터(04b5005)가 되었다.

  근데 이거 머지없이 덮어쓰는 방법 없나?

  <git pull 하기전에 파일들 복사해 두었다가 머지하라고 생긴 요상한 <<<, >>> 파일을 원래파일로 덮어쓰고 git add 하면 되시겠다>
   ----------------------------------------------
   > git revert [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>…​
   > git revert (--continue | --skip | --abort | --quit)
   {
      $ git revert --no-edit 0b062be
      [master 5d65f1e] Revert "다시 3: git revert 복구하면 이 메시지가 보여야 합니다."
      Date: Fri Oct 1 10:39:57 2021 +0900
      1 file changed, 1 insertion(+), 1 deletion(-)

      $ git reflog
      5d65f1e (HEAD -> master) HEAD@{0}: revert: Revert "다시 3: git revert 복구하면 이 메시지가 보여야 합니다."
      0b062be HEAD@{1}: reset: moving to 0b062be
      5b9153f (origin/master, origin/HEAD) HEAD@{2}: commit: 다시 4: git revert 를 위해 버려야할 수정 잘못된 수정입니다
      0b062be HEAD@{3}: commit: 다시 3: git revert 복구하면 이 메시지가 보여야 합니다.
      33b3c53 HEAD@{4}: commit (merge): 서버와 상태가 달라서 머지한 후
      5ff9fc6 HEAD@{5}: commit: 다시 2: git revert 복구하면 이 메시지가 보여야 합니다.
   }

5. 변경내역을 리모트에 push 
   {
      5.1 변경내역을 리모트에 push 하려하니 오류가 난다
      {
         $ git push
         To https://~~~~/_git_project
         ! [rejected]        master -> master (non-fast-forward)
         error: failed to push some refs to 'https://~~~~/_git_project'
         hint: Updates were rejected because the tip of your current branch is behind
         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.
      }
      5.2 그래서 pull 한 후 merge 한 다음 add & commit & push 했다
      {
         $ git pull
         Auto-merging authman/authman.cpp
         CONFLICT (content): Merge conflict in authman/authman.cpp
         Automatic merge failed; fix conflicts and then commit the result.
         ---------------
         이후 머지하고 커밋했다.
         -----------
         $ git push
         $ git reflog
         04b5005 (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: commit (merge): revert후 push 안되서 pull... merge 후 commitgk하는 중
         5d65f1e HEAD@{1}: revert: Revert "다시 3: git revert 복구하면 이 메시지가 보여야 합니다."
         0b062be HEAD@{2}: reset: moving to 0b062be
         5b9153f HEAD@{3}: commit: 다시 4: git revert 를 위해 버려야할 수정 잘못된 수정입니다
         0b062be HEAD@{4}: commit: 다시 3: git revert 복구하면 이 메시지가 보여야 합니다.
         33b3c53 HEAD@{5}: commit (merge): 서버와 상태가 달라서 머지한 후
      }
   }

6. 명령어 기록으로 분석
{
   --- 파일에 {다시 3: git revert 복구하면 이 메시지가 보여야 합니다.} 를 기록한 후 저장
   594  git add *
   595  git commit -m "다시 3: git revert 복구하면 이 메시지가 보여야 합니다."
   596  git push
   597  git reflog
   --- 파일내용을 {다시 4: git revert 를 위해 버려야할 수정 잘못된 수정입니다} 로 변경한 후 저장
   598  git status
   599  git add *
   600  git commit -m "다시 4: git revert 를 위해 버려야할 수정 잘못된 수정입니다"
   601  git push
   602  git reflog  <<== 위의 {1.HEAD 변경이력 확인} 참조
   603  git reset --hard 0b062be <<== 위의 {2. 복구할 HEAD 선택} 참조
   --- 이때 이미 실제 파일이 복원되어 있는 것을 확인 함
   604  git reflog
   605  git revert --no-edit 0b062be <<== 위의 {4. 복구한다} 참조
   606  git reflog  <<== 위의 {4. 복구한다} 참조
   607  git status
   608  git push
   609  git pull
   610  git status
   611  git add *
   612  git commit -m "revert후 push 안되서 pull... merge 후 commitgk하는 중"
   613  git push
   614  history
}

7. 결론
{
   작업중 잘못되면 과거 commit id로 reset 하고 revert 해서 현재 마스터와 merge 하고 comit 하면 되는 것이다.
   만일 파일 자체가 없어지거나 생긴경우는 confloct 는 없을 것이고 
   파일 내용이 변경되었다면 머지툴로 하나하나 머지 한 후 커밋해야 한다

   머지하지 않고 그냥 과거의 것으로 엎어치고 싶으면 reset 하고 전체를 다른 폴더로 복사해 둔다.

   나중에 머지하라고 뜨면, 머지하라고 생긴 요상한 <<<, >>> 파일을 원래파일로 덮어쓰고 git add 하면 되시겠다.
}