git: rebase -i 를 활용하여 이전 커밋 수정하기

YoungToMaturity·2022년 7월 24일
2

git

목록 보기
4/4
post-thumbnail

회사에서 일을 시작하게 된 후, 가장 크게 바뀐 점 중 하나는 무분별한 커밋이 더 이상 허용되지 않는 다는 것이었습니다. 지금까지 알고 있었던 지식이나 습관을 벗어 던질 필요가 있는 시기이기 때문에, 기록을 통해 남겨보고자 합니다.

시각적으로 커밋 로그 확인하기

source tree와 같은 git 시각화 툴은 여러가지가 있지만, 시각화 툴을 사용하지 않고도 여러 갈래로 나뉘어진 커밋 로그를 터미널에서 확인할 방법이 있습니다.
개인 기호에 따라 선호하는 방식이 다르겠지만, 개인적으로는 해당 명령어를 사용하는 것이 가장 편한 것 같습니다. 해당 명령어를 통해 확인한 현재 repository의 상태는 다음과 같습니다. main 브랜치에서 printName이란 로컬 브랜치를 생성하여 main.c 파일을 수정하고, upstream으로 origin/printName 브랜치에 push한 상황입니다.


요구되는 상황이 아래와 같다고 할때, 열심히 작업을 진행해보겠습니다!

인삿말만 출력하고 있는 main 브랜치의 main.c 에서 아래 사항들을 추가.

  • 나의 이름(yohwang) 출력 (완료)
  • 작별인사 출력 (진행중)

짠! 작업이 완료되었습니다. 이제 merge request를 작성하고 리뷰 후에 main 브랜치에 저의 코드가 추가되면 서비스에 저의 코드가 포함되겠네요!
하지만 아뿔사, 나름 꼼꼼히 확인했는데도 불구하고 치명적인 오류가 발견되었습니다.
기획에 따르면, 나의 이름은 yohwang인데, loopbackseal을 나의 이름으로 출력해주고 있네요. 혼자 하는 상황이었다면 Fix my name on main.c 라는 커밋을 추가했을 테지만, 두가지 기능 구현에 대해 두개의 커밋이 적절한 지금 상황에서는 Add print my name on main.c. 커밋을 수정하는 것이 적절해 보입니다!

rebase 활용

git rebase -i HEAD~3 커맨드를 사용하여 위에서 세번째 커밋까지의 목록을 불러와보겠습니다.
맨 아래 Add Goodbye ~~가 가장 최근의 커밋이고, 해당 커밋 기준 세번째 커밋인 Add printf on main.c.까지가 불려왔네요. 이 중에서 제가 수정하고자 하는 커밋은 가운데 있는 Add print my name on main.c.이기 때문에, 아래의 커맨드에 따라 pick을 e로 바꿔 보겠습니다!바꾼 후에 main.c를 확인하면, 아까와 달리 printf("Good bye!\n");이 없는 것을 확인할 수 있습니다.
이 코드를 기획안에 맞게 수정하면 아래와 같습니다.
이후 커밋에 Good bye가 추가되어 있기 때문에, 이 상황에서 git add main.c만 진행한 후, rebase를 마무리하는 명령어 git rebase --continue를 입력해보겠습니다!
위와 같은 창이 뜨게 되고, 별도의 커밋 메세지 수정은 필요하지 않기 때문에, 수정없이 창을 닫게 되면두 커밋 이상에서 같은 파일을 수정하였기 때문에 merge conflict가 발생하게 되는데, 이 상황에서 main.c를 열어보면,세가지 상황이 있는 것을 확인할 수 있는데, 제가 Add print my name on main.c.에서 수정한 두가지 상황 (후 HEAD, 전 parent of ~~)과 merge conflict가 발생한 Add Goodbye on main.c의 상황이 있네요! loopbackseal을 출력하던 상황에서 yohwang을 출력하도록 수정했기 때문에 Add Goodbye on main.c에서는 어떻게 수정을 했는지 반영해주면 될 것으로 보입니다. 따라서 아래 사진과 같이 충돌을 없애준 후,git add main.c를 해준 후에 rebase를 아래와 같이 마무리해주면 아까와 같이 커밋 메세지를 수정할 수 있는 창이 뜨고, 그 창을 닫아주면..!짠! 성공적으로 rebase되었다는 문구가 나오네요!! 이 상황에서 시각적으로 로그를 확인해보면 아래와 같습니다.Add print my name on main.c을 수정했기 때문에 두 갈래로 나뉘어 있는 것을 확인 할 수 있습니다. 이를 git push -f를 통해 force push를 하게 되면, 하나의 트리로 합쳐져 있는 것을 확인 할 수 있습니다! 또한, 이전의 커밋을 보면, 각 커밋의 my name이 loopbackseal이지만,
force push 이후에는 각 커밋의 my name이 yohwang으로 바뀐 것을 확인할 수 있습니다!
이처럼 오늘은 아주 간단한 예시를 통해 rebase를 통한 이전 커밋의 수정에 대해 기록해보았는데, 처음에는 이게 도대체 어떻게 되는건가 하는 생각에 그저 따라치기 급급했는데, 몇번 반복해서 손에 익고나니 마치 닥터 스트레인지가 된 것 같은 기분이 들고는 합니다!

제 부족한 설명이 누군가에게 조금이나마 도움이 됐으면 좋겠습니다 ㅎㅎ 읽어주셔서 감사합니다! 좋은 하루 되세요 😊

profile
iOS Developer

2개의 댓글

comment-user-thumbnail
2022년 8월 4일

전혀 몰랐던 기능에 대해 잘 배워갑니다! 써봐야겠어요~~

1개의 답글