Git에서 헷갈렸던 개념을 정리했다.
base를 재설정하는 작업으로, 브랜치의 시작점을 최신 커밋으로 옮겨 히스토리를 한 줄로 깔끔하게 만드는 것이다.
예를들어 feat/new 브랜치에서 작업중 다른 팀원이 main 브랜치에 머지를 했다고 해보자. 이 상태에서 그냥 Merge 하면 병합 커밋이 생겨서 히스토리가 지저분 해진다. 근데, Rebase를 사용하면 내 작업이 최신 main 기준으로 다시 쌓이기에 히스토리가 깔끔하게 쌓인다. 로컬에서 push 하기 전이나 혼자만 쓰는 브랜치인경우 리베이스를 자유롭게 해도 괜찮지만, 이미 push한 커밋이나 팀원들과 같이 작업하는 브랜치에서는 절대 리베이스를 하면 안 된다. 리베이스를 하면 해시가 바뀌면서 충돌이 발생되기 때문인데, 여기서 로컬 Branch와 원격 Branch에 차이를 명확히 알아야한다.
로컬 Branch는 내 컴퓨터에만 있는 브랜치이고, 원격 Branch는 GitHub에 push해서 팀원들과 공유되는 브랜치다. 쉽게 말하면 원격은 서버에 올라가 있는 것이고, 로컬은 내 컴퓨터에만 있는 것이다.
Rebase와 원격 Branch 리베이스를 하면, 커밋 해시가 바뀌는데, 해시는 각 커밋에 있는 ID 값이다. 원격 Branch에서 리베이스를 하면 이 해시가 바뀌기 때문에 팀원들이 가지고있는 해시와 달라져 충돌이 발생한다. 결국은 단순 오류로 오인해 force push 할수있는게 문제다.
Stash는 현재 작업 중인 변경사항을 임시로 저장해두는 기능이다. 예를 들어 작업 중에 main에 머지가 발생해서 pull을 받아야 하는 상황이 생겼다고 해보자. 이때 작업하던 내용이 그대로 남아있으면 충돌이 날 수 있기 때문에, 일단 Stash에 작업 내용을 넣어두고 pull을 받은 뒤 다시 꺼내서 이어서 작업하면 된다.
Squash Merge는 기존에 커밋된 작업을 전부 하나로 합쳐버리는 것이다. 예를 들어 feat/new 브랜치에서 작업하면서 A,B,C 커밋이 쌓였다고 해보자, 이때 Squash Merge 를 사용하면 해당 브랜치의 A,B,C 커밋을 전부 하나로 합쳐져서 main에 올라간다. 커밋 기록에 불필요 한 내용 혹은 지저분 할때 사용하지만, 남용하거나 기록이 남아야 하는경우에는 절대 사용하면안된다. 기록이 하나로 합쳐지면서 유실되기 때문이다.
참고 자료 : https://www.atlassian.com/git/tutorials/merging-vs-rebasing
PS. 사실.. 왜 이걸 공부했냐면
사실 이번에 리베이스를 공부하게 된 계기가 있다. 팀원이 포크 방식으로 협업하자고 했는데, 나는 팀 리포에서 바로 작업하는 게 더 편하다고 생각했다. 포크 방식은 주로 오픈소스나 외부 협업에서 쓰는 방식이고, 같은 팀끼리는 오히려 번거롭기만 하다고 생각했기 때문이다.
그래서 팀 리포에서 충돌 없이 작업할 수 있는 방법을 찾다가 리베이스를 공부하게 됐다. 사실 나는 업데이트가 안 된 상태로 브랜치를 만들어서 머지하면 충돌이 난다고 알고 있어서 아예 시도조차 안 했던 방식이었는데, 로컬에서 리베이스로 pull을 받으면 병합 커밋도 안 생기고 히스토리도 깔끔하고 충돌도 줄어든다는 걸 알게 됐다.아직도 많이 어렵고 이해가 안가는 부분도 있지만, 생각보다 재미있었고, 더 좋은 방식을 공부하게 된 계기가 됐다.