본문 바로가기

Android/Utility

[Git] Git에서 Head에 잘못 커밋했을 때 커밋 가져오는 방법

728x90

최근에 필자가 실무를 진행하면서 난생처음으로 check out을 한 상태로 작업을 진행하고 커밋을 하는 일이 발생했다.

처음 있던 일이었고, 그냥 당연히 sourceTree에서 커밋 리스트로 볼 수 있겠지라고 생각하고 원래 작업을 하려고 했던 브랜치로 체크아웃을 하는 순간, checkout 된 상태에서 작업한 리스트가 모두 안 보이는 것이 아닌가!

 

멘탈을 잡고 방법을 찾아보다 터미널을 사용해서 git에 commit 한 List를 가져오고, check out 하여 커밋을 가져오는 방법을 찾았고,
앞으로도 다양하게 사용할 수 있을 것이라 생각되어 포스팅을 하고자 한다.

 

필자처럼 소스트리나 포크같은 Git GUI 툴을 메인으로 사용하지 않는 사람이라면 다들 알고 있을 법한 방법이지만, 그렇지 않은 사람들에게 도움이 되었으면 한다.


우선, 
checkout을 한 다음에 커밋을 하면 다음과 같이 나오게 된다.

 

 

Head를 보면 알 수 있듯이 브랜치의 최신 커밋에 작업이 된 게 아닌, 브랜치의 중간에 체크아웃하여 커밋이 된 것을 알 수 있다.

 

이 상태에서 원래 브랜치로 누르면 다음과 같이 된다.

 

 

당연히 head 태그는 사라지겠지만 커밋 히스토리는 남아있을 것이라고 생각했지만, 위와 같이 커밋 된 데이터는 다 날아간 것 처럼 안보이게 된다.

 

자, 이제 날아간 refactor: 로 시작하는 커밋을 찾아보도록 하자.

 

우선,

터미널을 열 수 있는 앱을 사용하여 해당 프로젝트가 있는 위치로 이동하자.

 

해당 위치로 이동했으면, 위의 사진과 같이 git log 혹은 git reflog 라는 커맨드를 사용해서 검색을 해보도록 하자.

git log는 git에 commit된 데이터의 디테일한 정보들을 보여주고, git reflog 커맨드를 사용하면 git log에서 보여주는 정보들 중 header 부분만 보여주는 커맨드이다.

 

데이터가 많으니 git reflog를 커맨드를 사용하면 다음과 같이 데이터가 나온다.

 

 

터미널의 이름을 보면 알 수 있듯이 git reflog를 사용한 결과이고, 데이터는 가장 최근 커밋 및 체크아웃되어있는 데이터가 위, 아래로 갈수록 과거의 커밋이 보이게 된다.

필자는 현재 원래 작업해야 할 브랜치를 체크아웃 하였기 때문에 head가 해당 브랜치로 되어있고, 바로 아래에 잘못 커밋하였던 하나의 커밋을 확인할 수 있다.

 

refactor: 로 시작한 커밋이고, 브랜치는 별도로 안 보이는 대신 HEAD라는 키워드가 앞에 붙어있는 것을 확인할 수 있다.

커밋 내용을 동일하게 하는 것이 아닌 작업 내용을 작성한다면 쉽게 찾을 수 있겠지만, 혹시 커밋 메시지의 head 부분을 공통으로 사용한다면 쉽게 찾지는 못할 것이다.

 

아무튼 해당 로그를 통해서 커밋이 살아있음을 확인할 수 있었으니, 이제 해당 커밋을 어떻게 가져와야 하는가 생각해 볼 때이다.

 

일단, 해당 커밋으로 head를 이동하기 위해서는 당연히 해당 커밋 코드를 사용해서 checkout을 해주면 된다.

 

 

git checkout 'commit code' 를 사용하면 이처럼 메시지가 나오게 된다.

 

해당 내용을 해석하면 간단하게 다음과 같다.

 

지금 분리된 Head 상태에 있다. 브랜치로 다시 전환하여 브랜치에 영향을 주지 않고 이 상태에서 수행한 커밋을 삭제할 수 있다.

생성한 커밋을 유지하기 위해 새 브랜치를 생성하려면 switch 명령과 함께 -c 키워드를 사용해라.

 

자 내용을 읽어보니, 지금 필자가 당황했던 상황 자체가 당연히 제공되는 기능이었고, 필자는 이것을 모르고 냅다 check out 된 부분에 커밋을 때리고 해당 내용을 찾으려고 했던 것이다.

또한, 커밋을 유지하기 위해서는 위의 커맨드를 사용하여 브랜치를 만들라는 것을 보아, 커밋을 살리기 위해서는 브랜치를 만들어야 하는 것 같다.

 

위에 나온 커맨드를 사용해도 상관은 없지만, 필자는 조금 다른 커맨드를 사용해서 작업을 해보았다.

일단, 해당 커밋으로 체크아웃을 한 상태로 소스트리를 다시 확인해보면 다음과 같이 커밋이 돌아온 것을 확인할 수 있다.

 

롤백 된 것을 보여주기 위해 새로 캡쳐하고, 새롭게 내용을 가렸다.

 

우선, 이 상태에서 새로운 브랜치를 만들어 준다.

 

 

우선 경로를 보면 위에서 checkout 한 커밋 코드가 찍혀있는 것을 볼 수 있다.

git checkout -b 'branch name' 을 사용하게 되면, 위에 가이드가 나왔던 switch 커맨드와 동일한 역할을 하게 된다.

 

즉, 현재 head에 위치하는 커밋을 작성한 브랜치 이름의 브랜치로 체크아웃한다는 이야기이다.

이렇게 브랜치를 새로 생성하여 체크아웃한 후에, 다시 git reflog를 통해 데이터를 확인해보자.

 

 

이처럼, 기존 Head에 들어가 있던 커밋도 tempbranch로 변경된 것을 확인할 수 있으며, 해당 커밋이 tempbranch로 이동되었다는 로그까지 확인이 가능하다.

 

여기까지 진행했으면, 소스트리에서도 새로운 브랜치로 커밋이 되어있기 때문에 데이터를 확인할 수 있지만 지금까지 커맨드로 작업을 했으니 push까지 커맨드로 처리하도록 한다.

 

 

git push origin 'new branch'라는 커맨드를 통해 새로운 브랜치를 origin으로 push를 하게 된다.

물론 붉은색 칸을 쳐둔 부분을 보면 알 수 있듯이, push를 하는 것이기 때문에 로그인 한 github 계정의 비밀번호를 입력해야 정상적으로 push를 진행할 수 있는데,

이때 입력이 필요한 비밀번호는 로그인할 때 입력하는 비밀번호가 아닌, github 계정을 맨 처음 등록할 때 생성했던 Access Token을 사용해야 한다.

 

이렇게 커밋까지 커맨드로 잘 수행한 다음, 소스트리를 보면 다음과 같은 결과를 볼 수 있다.

 

정상적으로 커밋이 되었고, 소스트리에서도 확인이 가능하다.

 

지금 테스트는 1개의 커밋으로 진행을 하였는데, 당연하다시피 여러 개의 커밋도 동일한 방법으로 처리가 가능하다.

가장 마지막에 커밋한 내용을 check out 하고 새로운 브랜치를 만들어서 커밋하게 되면 check out 한 후에 진행한 모든 커밋이 새롭게 생성한 브랜치의 히스토리에 들어가 있게 된다.


생각보다 자세하게, 모든 스텝을 작성해 둔 이유는 필자가 나중에 또 실수했을 때 까먹을 수도 있다고 생각하여 참고용으로 작성해 보았다.

 

처음에 check out 한 후에 커밋을 한 게 왜 사라지는 것인가? 다 보이게 남아있어야 하는 것은 아닌가?라고 생각했지만 사라지는 것들도 기능의 일부라는 것, 그리고 그것들을 쉽게 되돌릴 수 있다는 것을 이번 기회를 통해 알게 되었다.

 

지금까지 몇 년간 개발을 해오면서 소스트리와 같은 git gui tool을 사용해 왔는데, 이렇게 실수를 한 것이 처음이었기 때문에 생각보다 많은 당황을 했던 것 같다.

아니 커밋을 했는데 데이터가 남아있지 않을 리가 없지 하고 생각함과 동시에, 커밋 한 내용도 한두 개도 아니고 이거 못 가져오면 언제 이걸 다시 작업하지..라는 생각 때문에 멘탈이 좋지 않았다.

 

그래도 역시 데이터는 당연하게 남아있었고, 생각보다 쉽게 가져올 수 있어서 다행이라고 생각했으며,

GUI로만 사용하다 보니 당연히 알아야 할 git command를 몰라서 당황했다고 생각하니 어이가 없었다.

 

추후에 git command도 기회가 되면 찾아보고, 학습하여 포스팅을 해야겠다.

728x90