Git: Nhật ký Git nâng cao


Đăng ký nhận thông báo về những video mới nhất

Mục đích của bất kỳ hệ thống kiểm soát phiên bản nào là ghi lại các thay đổi đối với mã của bạn. Điều này cung cấp cho bạn sức mạnh để quay lại lịch sử dự án của bạn để xem ai đã đóng góp những gì, tìm ra lỗi được giới thiệu ở đâu và hoàn nguyên các thay đổi có vấn đề. Nhưng, có sẵn tất cả lịch sử này là vô ích nếu bạn không biết cách điều hướng nó. Đó là nơi lệnh git log xuất hiện.

Đến bây giờ, bạn đã biết lệnh git log cơ bản để hiển thị các xác nhận. Nhưng, bạn có thể thay đổi đầu ra này bằng cách chuyển nhiều tham số khác nhau vào nhật ký git.

Các tính năng nâng cao của nhật ký git có thể được chia thành hai loại: định dạng cách hiển thị từng cam kết và lọc các cam kết được bao gồm trong đầu ra. Cùng với nhau, hai kỹ năng này cung cấp cho bạn sức mạnh để quay trở lại dự án của bạn và tìm thấy bất kỳ thông tin nào bạn có thể cần.

Định dạng Nhật ký đầu ra

Đầu tiên, bài viết này sẽ xem xét nhiều cách git logcó thể định dạng đầu ra của đầu ra. Hầu hết trong số này đến dưới dạng cờ cho phép bạn yêu cầu nhiều hoặc ít thông tin từ đó git log.

Nếu bạn không thích định git logdạng mặc định, bạn có thể sử dụng git configchức năng răng cưa để tạo lối tắt cho bất kỳ tùy chọn định dạng nào được thảo luận bên dưới. Vui lòng xem trong Lệnh git config để biết cách thiết lập bí danh.

Một đường thẳng

Các --onelinecờ ngưng tụ từng cam kết một dòng đơn. Theo mặc định, nó chỉ hiển thị ID cam kết và dòng đầu tiên của thông điệp cam kết. git log --onelineĐầu ra điển hình của bạn sẽ trông giống như thế này:

0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base

Điều này rất hữu ích để có được một cái nhìn tổng quan cấp cao về dự án của bạn.

Trang trí

Nhiều lần rất hữu ích để biết chi nhánh hoặc thẻ mà mỗi cam kết được liên kết với. Các --decoratelá cờ làm cho git loghiển thị tất cả các tài liệu tham khảo (ví dụ, ngành, thẻ, vv) mà điểm đến từng cam kết.

Điều này có thể được kết hợp với các tùy chọn cấu hình khác. Ví dụ: chạy git log --oneline --decoratesẽ định dạng lịch sử cam kết như vậy:

0e25143 (HEAD, master) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base

Điều này cho bạn biết rằng cam kết hàng đầu cũng được kiểm tra (ký hiệu là HEAD) và đó cũng là mẹo của masterchi nhánh. Cam kết thứ hai có một nhánh khác được gọi là nó featurevà cuối cùng là cam kết thứ 4 được gắn thẻ là v0.9.

Các nhánh, thẻ HEADvà lịch sử cam kết gần như là tất cả thông tin có trong kho Git của bạn, vì vậy điều này cung cấp cho bạn cái nhìn đầy đủ hơn về cấu trúc logic của kho lưu trữ của bạn.

Khác biệt

Các git loglệnh bao gồm nhiều tùy chọn để hiển thị diffs với từng cam kết. Hai trong số các tùy chọn phổ biến nhất là --statvà -p.

Các --stattùy chọn hiển thị số lượng chèn và xóa bỏ cho mỗi tập tin bị thay đổi bởi mỗi cam kết (lưu ý rằng thay đổi một dòng được biểu diễn dưới dạng 1 chèn và 1 xóa). Điều này hữu ích khi bạn muốn một bản tóm tắt ngắn gọn về những thay đổi được giới thiệu bởi mỗi cam kết. Ví dụ: cam kết sau đây đã thêm 67 dòng vào hello.pytệp và xóa 38 dòng:

commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date: Fri Jun 25 17:30:28 2014 -0500
Add a new feature
hello.py | 105 ++++++++++++++++++++++++-----------------
1 file changed, 67 insertion(+), 38 deletions(-)

Số lượng +và -dấu hiệu bên cạnh tên tệp hiển thị số lượng thay đổi tương đối cho mỗi tệp được thay đổi bởi cam kết. Điều này cung cấp cho bạn ý tưởng về nơi có thể tìm thấy các thay đổi cho từng cam kết.

Nếu bạn muốn xem các thay đổi thực tế được giới thiệu bởi mỗi cam kết, bạn có thể chuyển -ptùy chọn này git log. Điều này xuất ra toàn bộ bản vá thể hiện cam kết đó:

commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date: Fri Jun 25 17:31:57 2014 -0500
Fix a bug in the feature
diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")

Đối với các cam kết có nhiều thay đổi, kết quả đầu ra có thể trở nên khá dài và khó sử dụng. Thường xuyên hơn không, nếu bạn đang hiển thị một bản vá đầy đủ, có lẽ bạn đang tìm kiếm một thay đổi cụ thể. Đối với điều này, bạn muốn sử dụng tùy chọn pickaxe.

Shortlog

Các git shortloglệnh là một phiên bản đặc biệt của git logthiết kế để tạo thông báo phát hành. Nó nhóm từng cam kết theo tác giả và hiển thị dòng đầu tiên của mỗi thông điệp cam kết. Đây là một cách dễ dàng để xem ai đang làm việc trên cái gì.

Ví dụ: nếu hai nhà phát triển đã đóng góp 5 lần cam kết cho một dự án, thì kết git shortlogquả đầu ra có thể giống như sau:

Mary (2):
Fix a bug in the feature
Fix a serious security hole in our framework
John (3):
Add the initial code base
Add a new feature
Merge branch 'feature'

Theo mặc định, git shortlogsắp xếp đầu ra theo tên tác giả, nhưng bạn cũng có thể chuyển -ntùy chọn để sắp xếp theo số lần xác nhận trên mỗi tác giả.

Đồ thị

Các --graphtùy chọn vẽ một đồ thị ASCII đại diện cho cấu trúc chi nhánh của lịch sử cam kết. Điều này thường được sử dụng cùng với các lệnh --onelinevà --decorateđể giúp dễ dàng xem cam kết nào thuộc về nhánh nào:

git log --graph --oneline --decorate

Đối với một kho lưu trữ đơn giản chỉ có 2 nhánh, điều này sẽ tạo ra các mục sau:

* 0e25143 (HEAD, master) Merge branch 'feature'
|\
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base

Những buổi biểu diễn dấu mà chi nhánh cam kết là trên, vì vậy đồ thị trên cho chúng ta biết 23ad9advà 16b36c6cam kết đang ở trên một chi nhánh chủ đề và phần còn lại là trên masterchi nhánh.

Trong khi đây là một lựa chọn tốt đẹp cho kho đơn giản, bạn có lẽ tốt hơn với một công cụ trực quan đầy đủ tính năng hơn như gitkhoặc Sourcetree  cho các dự án được phân nhánh nhiều.

Định dạng tùy chỉnh

Đối với tất cả các git lognhu cầu định dạng khác của bạn , bạn có thể sử dụng --pretty=format:"<string>"tùy chọn. Điều này cho phép bạn hiển thị từng cam kết tuy nhiên bạn muốn sử dụng printftrình giữ chỗ kiểu.

Ví dụ, các %cn%hvà %cdcác nhân vật trong các lệnh sau đây được thay thế bằng tên committer, viết tắt là cam kết băm, và ngày committer, tương ứng.

git log --pretty=format:"%cn committed %h on %cd"

Điều này dẫn đến định dạng sau cho mỗi cam kết:

John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500
John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500
Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500
John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500

Danh sách đầy đủ các trình giữ chỗ có thể được tìm thấy trong phần Định dạng đẹp của git logtrang hướng dẫn.

Ngoài việc cho phép bạn chỉ xem thông tin mà bạn quan tâm, --pretty=format:"<string>"tùy chọn này đặc biệt hữu ích khi bạn đang cố gắng chuyển git logđầu ra sang một lệnh khác.

Lọc lịch sử cam kết

Định dạng cách mỗi cam kết được hiển thị chỉ là một nửa trận chiến học tập git log. Nửa còn lại là hiểu làm thế nào để điều hướng lịch sử cam kết. Phần còn lại của bài viết này giới thiệu một số cách nâng cao để chọn ra các cam kết cụ thể trong lịch sử dự án của bạn bằng cách sử dụng git log. Tất cả những thứ này có thể được kết hợp với bất kỳ tùy chọn định dạng nào được thảo luận ở trên.

Theo số lượng

Tùy chọn lọc cơ bản nhất cho git loglà giới hạn số lượng xác nhận được hiển thị. Khi bạn chỉ quan tâm đến một vài lần xác nhận gần đây, điều này sẽ giúp bạn tránh được những rắc rối khi xem tất cả các cam kết trong một trang.

Bạn có thể giới hạn git logđầu ra bằng cách bao gồm -<n>tùy chọn. Ví dụ: lệnh sau sẽ chỉ hiển thị 3 lần xác nhận gần đây nhất.

git log -3

Theo ngày

Nếu bạn đang tìm kiếm một cam kết từ một khung thời gian cụ thể, bạn có thể sử dụng --afterhoặc --beforecờ để lọc các cam kết theo ngày. Cả hai đều chấp nhận một loạt các định dạng ngày làm tham số. Ví dụ: lệnh sau chỉ hiển thị các cam kết đã được tạo sau ngày 1 tháng 7 năm 2014 (bao gồm):

git log --after="2014-7-1"

Bạn cũng có thể vượt qua trong các tài liệu tham khảo tương đối như "1 week ago"và "yesterday":

git log --after="yesterday"

Để tìm kiếm một cam kết đã được tạo giữa hai ngày, bạn có thể cung cấp cả ngày --beforevà --afterngày. Ví dụ: để hiển thị tất cả các cam kết được thêm vào giữa ngày 1 tháng 7 năm 2014 đến ngày 4 tháng 7 năm 2014, bạn sẽ sử dụng như sau:

git log --after="2014-7-1" --before="2014-7-4"

Lưu ý rằng các cờ --sincevà --untilđồng nghĩa với --aftervà --before, tương ứng.

Tác giả

Khi bạn chỉ tìm kiếm các cam kết được tạo bởi một người dùng cụ thể, hãy sử dụng --authorcờ. Điều này chấp nhận một biểu thức chính quy và trả về tất cả các xác nhận mà tác giả phù hợp với mẫu đó. Nếu bạn biết chính xác người bạn đang tìm kiếm, bạn có thể sử dụng một chuỗi cũ đơn giản thay vì một biểu thức thông thường:

git log --author="John"

Điều này hiển thị tất cả các cam kết có tác giả bao gồm tên John . Tên tác giả không cần phải là một đối sánh chính xác , nó chỉ cần chứa cụm từ được chỉ định.

Bạn cũng có thể sử dụng các biểu thức thông thường để tạo các tìm kiếm phức tạp hơn. Ví dụ: lệnh sau tìm kiếm các xác nhận của Mary hoặc John .

git log --author="John\|Mary"

Lưu ý rằng email của tác giả cũng được bao gồm với tên của tác giả, vì vậy bạn cũng có thể sử dụng tùy chọn này để tìm kiếm qua email.

Nếu quy trình làm việc của bạn tách các ủy viên khỏi các tác giả, --committercờ sẽ hoạt động theo cùng một kiểu.

Bằng tin nhắn

Để lọc các xác nhận bằng thông điệp cam kết của họ, hãy sử dụng --grepcờ. Điều này hoạt động giống như --authorcờ được thảo luận ở trên, nhưng nó phù hợp với thông điệp cam kết thay vì tác giả.

Ví dụ: nếu nhóm của bạn bao gồm các số vấn đề có liên quan trong mỗi thông báo cam kết, bạn có thể sử dụng một số thứ như sau để rút ra tất cả các cam kết liên quan đến vấn đề đó:

git log --grep="JRA-224:"

Bạn cũng có thể truyền -itham số git logđể làm cho nó bỏ qua các trường hợp khác nhau trong khi khớp mẫu.

Bằng tệp

Nhiều lần, bạn chỉ quan tâm đến những thay đổi xảy ra với một tệp cụ thể. Để hiển thị lịch sử liên quan đến một tệp, tất cả những gì bạn phải làm là vượt qua trong đường dẫn tệp. Ví dụ: sau đây trả về tất cả các xác nhận đã ảnh hưởng đến tệp foo.pyhoặc bar.pytệp:

git log -- foo.py bar.py

Các --tham số được sử dụng để nói git logrằng lập luận tiếp theo là đường dẫn tập tin và tên không chi nhánh. Nếu không có cơ hội trộn nó với một nhánh, bạn có thể bỏ qua --.

Theo nội dung

Cũng có thể tìm kiếm các cam kết giới thiệu hoặc xóa một dòng mã nguồn cụ thể. Điều này được gọi là một cái cuốc , và nó có hình thức -S"<string>". Ví dụ: nếu bạn muốn biết khi nào chuỗi Hello, World! đã được thêm vào bất kỳ tập tin nào trong dự án, bạn sẽ sử dụng lệnh sau:

git log -S"Hello, World!"

Nếu bạn muốn tìm kiếm bằng biểu thức thông thường thay vì chuỗi, bạn có thể sử dụng -G"<regex>"cờ thay thế.

Đây là một công cụ gỡ lỗi rất mạnh, vì nó cho phép bạn xác định tất cả các cam kết ảnh hưởng đến một dòng mã cụ thể. Nó thậm chí có thể hiển thị cho bạn khi một dòng được sao chép hoặc di chuyển sang tệp khác.

Theo phạm vi

Bạn có thể vượt qua một loạt các cam kết để git logchỉ hiển thị các cam kết có trong phạm vi đó. Phạm vi được chỉ định theo định dạng sau, ở đâu <since>và <until>là các tham chiếu cam kết:

git log <since>..<until>

Lệnh này đặc biệt hữu ích khi bạn sử dụng các tham chiếu nhánh làm tham số. Đó là một cách đơn giản để thể hiện sự khác biệt giữa 2 chi nhánh. Hãy xem xét các lệnh sau:

git log master..feature

Các master..featurephạm vi chứa tất cả các cam kết rằng đang ở trong featurengành, nhưng không nằm trong masterchi nhánh. Nói cách khác, đây là khoảng cách featuređã tiến triển kể từ khi nó rẽ nhánh master. Bạn có thể hình dung điều này như sau:

Phát hiện một ngã ba trong lịch sử bằng cách sử dụng phạm vi

Lưu ý rằng nếu bạn chuyển đổi thứ tự của phạm vi ( feature..master), bạn sẽ nhận được tất cả các cam kết trong master, nhưng không phải trong feature. Nếu git logđầu ra cam kết cho cả hai phiên bản, điều này cho bạn biết rằng lịch sử của bạn đã được chuyển hướng.

Lọc cam kết hợp nhất

Theo mặc định, git logbao gồm các cam kết hợp nhất trong đầu ra của nó. Nhưng, nếu nhóm của bạn có chính sách luôn hợp nhất (nghĩa là bạn hợp nhất các thay đổi ngược dòng thành các nhánh chủ đề thay vì đẩy lại nhánh chủ đề lên nhánh ngược dòng), bạn sẽ có rất nhiều cam kết hợp nhất bên ngoài trong lịch sử dự án của bạn.

Bạn có thể ngăn không cho git loghiển thị các cam kết hợp nhất này bằng cách chuyển --no-mergescờ:

git log --no-merges

Mặt khác, nếu bạn chỉ quan tâm đến các cam kết hợp nhất, bạn có thể sử dụng --mergescờ:

git log --merges

Điều này trả về tất cả các cam kết có ít nhất hai cha mẹ.

Tóm lược

Bây giờ bạn sẽ khá thoải mái khi sử dụng git logcác tham số nâng cao để định dạng đầu ra của nó và chọn cam kết bạn muốn hiển thị. Điều này cung cấp cho bạn sức mạnh để rút ra chính xác những gì bạn cần từ lịch sử dự án của bạn.

Những kỹ năng mới này là một phần quan trọng trong bộ công cụ Git của bạn, nhưng hãy nhớ rằng git lognó thường được sử dụng cùng với các lệnh Git khác. Một khi bạn đã tìm thấy cam kết bạn đang tìm kiếm, bạn thường vượt qua nó đi đến git checkoutgit reverthoặc một số công cụ khác để thao túng lịch sử cam kết của bạn. Vì vậy, hãy chắc chắn tiếp tục tìm hiểu về các tính năng nâng cao của Git.

Đăng ký nhận thông báo về những video mới nhất
« Prev: Git: Đặt lại, kiểm tra, và hoàn nguyên
» Next: Git: Refs và Reflog
Copied !!!