Git의 Staging Area는 어떤 점이 유용한가

Git에는 Staging Area라는 공간이 있다. 어떤 변경사항이 저장소에 커밋되기 전에, 반드시 거쳐야만 하는 중간단계이다.

다른 버전관리도구에는 이에 정확히 대응하는 것은 없다. 저장소가 추적하는(관심의 대상이 되는) 파일들의 목록을 유지하고, 그 파일들에 대한 메타데이터를 관리하는 것은 다른 저장소들도 하는 일이지만, Git 처럼 커밋될 예정인 파일의 내용들까지 기억하지는 않는다.

이 Staging Area의 존재는 처음 Git을 사용하는 입장에서는 그저 불편만 안겨주고 이해만 더디게 만들어주는 목적불명의 무언가에 지나지 않는다. 다른 SCM에선 파일을 고치고 바로 커밋하면 되었는데, Git은 반드시 그 전에 add를 해 줘야 한다. 이런 비용을 감수하면서까지 Git이 Staging Area라는 공간을 사용자들에게 노출시키고 있는 이유는 무엇일까. 어떤 상황에서 Staging Area가 유용한지 살펴보면서 이해해보자.

일부분만 커밋할 때

Working directory에서 코드를 고칠 때는 자유롭게 고치고 싶다. 하지만 커밋할때는 atomic하게 하고 싶다. 이를 가능하게 하려면 커밋할 때 working directory 전체가 아니라 부분만 커밋하면 될 것이다.

staging area라는 것이 없다고 가정해보자. ‘커밋될 예정인 내용들’을 디스크에 저장해 둘 공간이 없으므로, 커밋할 때 어느 부분을 커밋할지 한번에 결정해야 한다. 한번에 어렵지 않게 결정할 수도 있지만 시간을 들여 생각해야 할 수도 있다. 시간을 들여 조금씩 커밋할 부분을 결정해 나간다고 하면, 그 시간동엔 나의 결정사항들은 메모리상에 존재해야 한다. 메모리에 올라와있는 정보는 디스크에 저장되어 있는 정보보다 다루기 까다롭다. Staging Area에 저장되어있는 ‘곧 커밋될 예정인 내용’들은 쉽게 git diff --staged등의 명령으로 확인할 수 있겠지만, 이것이 메모리에 올라와있는 상태라면, 해당 메모리 영역을 사용하고 있는 프로세스를 찾아서 물어봐야 알 수 있다. 실수로 그 프로세스를 죽였다면 공들여 커밋을 준비하던 것이 허사가 된다. (( 커밋을 깔끔하게 만드는데 과도하게 공을 들인다는 생각이 드는가? 하지만 이런 개발자들이 실제로 있다. ))

충돌을 해결할 때

충돌을 해결해야 하는 상황에서도 비슷한 문제가 있다. 5개의 파일을 머지했는데 그 중 2개에서 충돌이 발생했다고 해 보자. 3개의 파일은 그냥 커밋하면 되고 2개는 충돌을 해소(resolve)해줘야한다. 여기서도 위와 같은 문제가 생긴다. 큰 규모의 충돌이 발생한 경우 이를 해결하는 것은 상당히 시간이 들어가는 일이고, 이를 위한 작업 데이터를 메모리에만 올려놓는 것은 참으로 불안하다. 따라서 이 정보 역시 Staging Area와 같이 디스크의 어떤 공간에 저장해두는 것이 훨씬 좋을 것이다. 이것은 Staging Area가 없는 Subversion이라도 마찬가지다. 서브버전은 어떤 파일이 충돌했는지 ‘파일 상태’를 기억한다. 그러나 이보다는 Git의 방식이 더 낫다. 서브버전은 파일 단위로 충돌 여부를 기억하기 때문에, 파일의 일부분만 충돌을 해소한 후 커밋하는 것은 매우 어렵기 때문이다. Git이라면 간단하다. 충돌이 발생한 파일에서, 필요한 만큼만 충돌을 해소하고 그 부분만 add하여 커밋하면 된다.

커밋 다시하기

commit --amend 명령으로 커밋을 다시 할 때도 Staging Area의 존재는 빛을 발한다. 커밋을 다시 할 때 로그메시지만 고치는 것이 아니라 파일들도 좀 고치고 싶다면, commit --amend 전에 파일을 고쳐서 Staging Area에 add하기만 하면 된다. Staging Area가 없었다면 commit --amend시에 Git에게 다른 방법으로 패치를 전달해주었어야 했을 것이다.

요약

Staging Area는 단순하지만 유용한 저장공간이다. 많은 Git의 명령들이 Staging Area를 활용하여 Git을 더욱 생산적인 도구로 만들어준다.

물론 Staging Area라는 생소한 개념이 Git의 진입장벽을 더욱 높이는 것은 사실이지만, 그럼에도 불구하고 나를 비롯한 Git을 즐겨쓰는 많은 개발자들에게 Staging Area는 여전히 필수불가결한 존재이다. 누군가 이해하기 쉬우면서도 현 Staging Area에 대한 요구를 흡수할(혹은 불필요하게 만들) 수 있는 어떤 개념을 만들어낸다면 몰라도 그 전까지는 Git의 핵심 기능이자 특징으로서의 지위가 변하는 일은 없을 것이다.

관련글

며칠전에 Git 메일링리스트에 Staging Area가 왜 필요한지에 대해 질문을 했었는데, 많은 분들이 회신을 주셨다. 그 회신들을 통해 알게 된, Staging Area의 이점에 대해 설명하는 두 개의 글을 소개한다.

Git의 Staging Area는 어떤 점이 유용한가”에 대한 8개의 생각

    1. 창우님 반갑습니다 🙂 퇴고를 안해서 다소 어지러운 글이었을텐데 읽어주시고 댓글도 주시니 정말 고맙습니다.

      좋아요

  1. 예전에도 한번 들렸던 블로그 였는데 응준님 블로그였군요 🙂 이번에 사내에 git 적용하느라 여기저기 기웃거리다가 들렀습니다. 좋은 글 잘 읽고 갑니다.

    (코세라 스터디에 나오는 정대원 이라고 합니다)

    좋아요

  2. commit이 바로 안 되네. staging area라는 게 있네. 이게 git 첫인상이었습니다.

    staging area를 분리해서 얻는 잇점이 궁금했습니다. 이 글을 읽어보니 이해가 되네요. 좋은 글 감사합니다.

    좋아요

댓글 남기기