버그를 수정하다 보면 가장 빠르고 눈에 띄는 변경이 항상 최선의 선택은 아닙니다. 그리고 눈앞에 있는 코드만으로 전체 이야기를 알 수 없습니다. 쉬운 해결책을 넘어서려면 왜 그런 결정이 내려졌는지 알아야 합니다. 즉, 코드 뒤에 숨겨진 역사를 이해해야 하는 것입니다. 코드를 자신 있게 변경하는 데 필요한 지식을 얻을 수 있는 훌륭한 방법 세 가지를 소개합니다.
git blame 활용하기
git blame을 사용하면 프로젝트 내 모든 코드 줄의 모든 버전을 추적해서, 해당 코드가 처음 작성된 시점까지 거슬러 올라갈 수 있습니다.
예를 들어 ActiveJob의 queue_name.rb 파일을 살펴보다가 queue_name_delimiter 속성이 정확히 무엇인지 궁금해졌다고 가정해 봅시다.
included do
class_attribute :queue_name, instance_accessor: false
class_attribute :queue_name_delimiter, instance_accessor: false
self.queue_name = default_queue_name
self.queue_name_delimiter = '_' # 기본 구분자를 '_'로 설정
end
여기에 git blame을 실행할 수 있습니다.
$ git blame queue_name.rb
...
da6a86f8 lib/active_job/queue_name.rb (Douwe Maan 2014-06-09 18:49:14 +0200 34) included do
1e237b4e activejob/lib/active_job/queue_name.rb (Cristian Bica 2014-08-25 17:34:50 +0300 35) class_attribute :queue_name, instance_accessor: false
11ab04b1 activejob/lib/active_job/queue_name.rb (Terry Meacham 2014-09-23 15:51:44 -0500 36) class_attribute :queue_name_delimiter, instance_accessor: false
11ab04b1 activejob/lib/active_job/queue_name.rb (Terry Meacham 2014-09-23 15:51:44 -0500 37)
...
각 줄마다 다음 정보를 순서대로 확인할 수 있습니다.
- 해당 줄을 가장 최근에 변경한 리비전(예:
11ab04b1) - 그 커밋의 작성자 이름
- 변경이 이루어진 날짜
그 코드 줄에 대해 더 자세히 알고 싶다면 리비전 번호가 필요합니다. 해당 ID(11ab04b1 부분)를 git show나 git log에 넘기면 됩니다.
$ git show 11ab04b1
commit 11ab04b11170253e96515c3ada6f2566b092533a
Author: Terry Meacham <zv1n.fire@gmail.com>
Date: Tue Sep 23 15:51:44 2014 -0500
Added queue_name_delimiter attribute.
- Added ActiveJob::Base#queue_name_delimiter to allow for
developers using ActiveJob to change the delimiter from the default
('_') to whatever else they may be using (e.g., '.', '-', ...).
- Updated source guide to include a blurb about the delimiter.
diff --git a/activejob/lib/active_job/queue_name.rb b/activejob/lib/active_job/queue_name.rb
index d167617..6ee7142 100644
...
훌륭하죠! 이제 그 변경 사항이 무엇이고 왜 유용한지 조금 더 알게 되었고, 이전에 놓쳤을 수도 있는 Rails 가이드의 관련 부분도 확인하게 됩니다.
여기서는 운이 좋았습니다. 찾으려던 정보를 바로 발견했으니까요. 하지만 git blame은 해당 줄이 변경된 가장 최근 이력만 보여줍니다. 때로는 두세 커밋을 더 거슬러 올라가야 원하는 것을 찾을 수 있습니다.
더 오래된 커밋을 보려면 git blame을 다시 실행하면 됩니다. 단, 이번에는 방금 찾은 커밋의 바로 이전 리비전을 인자로 넘깁니다. (git에서는 리비전 뒤에 ^를 붙여 '특정 커밋의 이전 커밋'을 표현할 수 있습니다. 예: 11ab04b1^)
$ git blame 11ab04b1^ queue_name.rb
...
da6a86f8 lib/active_job/queue_name.rb (Douwe Maan 2014-06-09 18:49:14 +0200 33) included do
1e237b4e activejob/lib/active_job/queue_name.rb (Cristian Bica 2014-08-25 17:34:50 +0300 34) class_attribute :queue_name, instance_accessor: false
94ae25ec activejob/lib/active_job/queue_name.rb (Cristian Bica 2014-08-15 23:32:08 +0300 35) self.queue_name = default_queue_name
...
$ git blame 1e237b4e^ queue_name.rb
... 이런 식으로 계속 ...
하지만 이 방식은 상당히 번거롭습니다.
대신 여러분이 사용하는 에디터의 기능을 살펴보세요. 대부분의 에디터는 git blame으로 히스토리를 추적하는 과정을 쉽게 만들어 줍니다. 예를 들어 Emacs에서는 코드를 git blame으로 연 뒤 커서를 특정 줄에 놓고, a 키를 눌러 그 줄에 영향을 준 각 변경 사항을 하나씩 거슬러 올라갈 수 있으며, l과 D 키로 커밋에 대한 자세한 정보를 볼 수 있습니다.
혹시 여러분 팀이 커밋 메시지에 이슈 번호나 풀 리퀘스트를 함께 적어두나요? 그렇다면 git blame을 통해 한 줄의 코드에서 커밋으로, 그리고 그 커밋에 관한 논의까지 손쉽게 이동할 수 있습니다. 바로 그 논의에서 진짜 유용한 정보들을 찾을 수 있습니다.
GitHub Issues 검색하기
얼마 전 저는 Rails 4.2에서 respond_with가 제거되었다는 것을 알게 되었습니다. 문서에는 제거되었다는 사실만 명확히 나와 있을 뿐, 그 이유는 설명되어 있지 않았습니다.
GitHub의 이슈 검색창 뒤에는 엄청난 양의 유용한 지식이 숨겨져 있습니다. 어떤 기능이 왜 제거되었는지 알고 싶다면, 팀이 제거를 결정하면서 나눴던 논의보다 좋은 학습 자료는 없습니다.
Rails의 GitHub 저장소에서 respond_with를 검색하면 흥미로운 스레드들을 찾을 수 있습니다. 제거 이유를 파악하려고 한다면 아마 특정 스레드에 도달하게 될 텐데, 안타깝게도 그 스레드는 어떻게 제거되었는지만 설명하고 왜 제거되었는지는 다루지 않습니다.
하지만 그 스레드를 끝까지 읽다 보면, 실제로 respond_with 제거를 논의한 본래 스레드를 가리키는 댓글을 발견하게 됩니다. 바로 그곳에 진짜 핵심 정보가 있는 것이죠!
git blame과 마찬가지로, 처음부터 딱 원하는 정보를 찾지 못할 수도 있습니다. 참조를 따라가고, 댓글을 읽고, 링크를 클릭해야 할 때도 있습니다. 하지만 GitHub 이슈 검색은 올바른 출발점을 잡아주며, 약간의 호기심과 탐구심만 있다면 결국 원하는 답을 찾을 수 있습니다.
직접 질문하기
아쉽게도 프로젝트에 관한 모든 지식이 히스토리, 이슈, 풀 리퀘스트에 기록되어 있는 것은 아닙니다. 모든 것이 문서화되어 있지 않습니다.
따라서 그 코드를 처음 작성한 사람을 찾을 수 있다면 직접 물어보세요. 어떤 결정에 이르게 된 개발 문화와 아이디어를 알게 되고, 어디에도 기록되지 않았을 프로젝트의 역사를 배우게 됩니다. 또한 당시에는 선택되지 않았던 대안들에 대해서도 들을 수 있는데, 그중 일부는 지금 시점에서 시도해볼 만한 가치가 있을지도 모릅니다.
쉬운 방법은 위험할 수 있다
때로는 수정이 너무나 쉬워 보입니다. 딱 한 곳에서 이 예외 하나만 처리하면 퇴근할 수 있다고요!
하지만 이해하지 못한 코드를 변경하는 것은 위험합니다.
그러니 어떤 코드 줄이 어색해 보이거나, 어떤 결정이 이상해 보이거나, 어떤 호출이 불필요해 보일 때는 고고학자의 모자를 쓰세요. 그 코드에 대해 할 수 있는 모든 방법으로 최대한 많이 알아내야 합니다. 그래야 의도를 가지고 코드를 변경할 수 있고, 문제를 근본적으로 해결할 수 있습니다.