본문 바로가기

공부방/git

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

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의 핵심 기능이자 특징으로서의 지위가 변하는 일은 없을 것이다.

 

https://blog.npcode.com/2012/10/23/git%EC%9D%98-staging-area%EB%8A%94-%EC%96%B4%EB%96%A4-%EC%A0%90%EC%9D%B4-%EC%9C%A0%EC%9A%A9%ED%95%9C%EA%B0%80/