Khi bạn đi sửa bug, thay đổi nhanh, rõ ràng không phải lúc nào cũng tốt. Và mã trước mặt bạn không bao giờ là cả câu chuyện. Để đi xa hơn sửa dễ dàng, bạn phải biết tại sao quyết định nhất định được làm. Bạn phải hiểu lịch sử đằng sau mã. Và có ba cách tuyệt vời để học những gì bạn cần để tự tin thay đổi mã.
git blame
Với sự giúp đỡ của git blame, bạn có thể truy vết qua mọi phiên bản của mọi dòng mã trong dự án, tất cả cách trở lại khi nó được viết.
Ví dụ, giả sử bạn đang xem file queue_name.rb của ActiveJob, và bạn muốn biết thuộc tính queue_name_delimiter đó về cái gì:
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 = '_' # set default delimiter to '_' end
Bạn có thể chạy git blame trên nó:
$ 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) ...
Và cho mỗi dòng, theo thứ tự, bạn sẽ thấy:
- Revision thay đổi dòng đó gần nhất (
11ab04b1, ví dụ), - Tên tác giả commit đó,
- Và ngày thay đổi được làm.
Để học thêm về dòng mã đó, bạn sẽ cần số revision. Truyền id (phần 11ab04b1) cho git show hoặc 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 ...
Tuyệt! Bạn học thêm chút về thay đổi, tại sao nó hữu ích, và thấy phần Rails Guide về nó bạn có thể bỏ lỡ trước.
Ở đây, chúng ta khá may mắn. Chúng ta tìm thấy thông tin chúng ta tìm ngay lập tức. Nhưng git blame chỉ cho bạn thấy thời gian gần nhất dòng đó thay đổi. Và đôi khi, bạn sẽ không tìm thấy điều bạn tìm cho đến khi bạn đi hai hoặc ba commit về trước.
Để thấy commit trước, bạn có thể gọi git blame lại. Nhưng lần này, truyền revision trước commit git blame tìm. (Trong git, bạn có thể nói "commit trước commit khác" bằng cách đặt ^ sau revision, như 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 ... and so on ...
Đó khá gây choáng.
Thay vào đó, khám phá editor của bạn. Hầu hết editor làm truy vết lịch sử với git blame dễ dàng. Ví dụ, trong Emacs, sau git blame mã của bạn, đặt con trỏ trên một dòng. Sau đó, bạn có thể nhấn a để bước lùi qua mỗi thay đổi ảnh hưởng đến dòng đó, và dùng l và D để thấy chi tiết hơn về commit.
Team của bạn có tham chiếu issue number và pull request trong commit message không? Nếu có, git blame có thể dễ dàng đưa bạn từ một dòng mã, đến commit, đến thảo luận về commit đó. Và thảo luận đó là nơi bạn sẽ tìm thấy tất cả thứ thực sự hay.
GitHub Issues
Một lúc trước, tôi nhận ra Rails 4.2 đã gỡ bỏ respond_with. Trong tài liệu, rõ ràng nó bị gỡ, nhưng tôi không hiểu tại sao.
Có ton kiến thức tuyệt vời ẩn sau hộp tìm kiếm issue GitHub. Nếu bạn muốn biết tại sao tính năng bị gỡ, không nơi tốt hơn để học hơn thảo luận team có khi họ quyết định gỡ nó.
Vì vậy, nếu bạn tìm repo GitHub Rails cho respond_with, bạn sẽ tìm thấy một số thread thú vị về respond_with. Nếu bạn cố tìm ra tại sao nó bị gỡ, bạn có thể sẽ đến thread này. Thật không may, nó mô tả cách nó bị gỡ, nhưng không phải tại sao.
Sau đó trong thread đó, tuy nhiên, bạn sẽ tìm thấy comment trỏ đến thảo luận thực tế về gỡ respond_with. Đó là nơi thứ tốt!
Giống như git blame, bạn có thể không tìm thấy chính xác điều bạn tìm ngay lập tức. Bạn sẽ phải theo dõi tham chiếu, đọc comment, và nhấp link. Nhưng tìm kiếm issue GitHub sẽ đưa bạn bắt đầu ở đúng chỗ. Với một chút tò mò và tinh thần khám phá, bạn sẽ học được điều bạn đến tìm.
Hỏi câu hỏi
Thật không may, không phải tất cả kiến thức về dự án có thể tìm thấy trong lịch sử, issue, và pull request. Không phải mọi thứ được viết xuống.
Vì vậy nếu bạn tìm được người viết mã ban đầu, hãy hỏi về nó. Bạn sẽ khám phá văn hóa dev và ý tưởng dẫn đến quyết định. Bạn sẽ học lịch sử về dự án có thể chưa bao giờ được ghi lại. Và bạn sẽ nghe về con đường chưa bao giờ được đi, có thể thực sự hợp lý để thử bây giờ.
Cách dễ dàng có thể nguy hiểm
Đôi khi, sửa lỗi chỉ dường như rất dễ. Tất cả bạn phải làm là rescue exception này ở nơi này, và sau đó bạn có thể về nhà!
Nhưng nguy hiểm thay đổi mã bạn không hiểu.
Vì vậy khi một dòng mã dường như sai, hoặc quyết định dường như kỳ lạ, hoặc lời gọi dường như vô dụng, hãy đội mũ nhà khảo cổ học. Học nhiều nhất bạn có thể, bằng cách bạn có thể, về mã đó. Đó là cách bạn sẽ làm thay đổi mã có chủ đích, và sửa vấn đề ở gốc rễ.