Làm thế nào để có được lịch sử cam kết cho chỉ một chi nhánh?


128

Giả sử tôi đã tạo một chi nhánh mới my_experimenttừ đó mastervà thực hiện một số cam kết my_experiment. Nếu tôi thực hiện git logkhi nào my_experiment, tôi sẽ thấy các cam kết được thực hiện cho chi nhánh này, nhưng cũng là các cam kết được thực hiện mastertrước khi my_experimentschi nhánh được tạo.

Tôi sẽ thấy rất hữu ích khi thấy lịch sử của tất cả các cam kết cho my_experimentschi nhánh cho đến khi nó chạm vào việc tạo ra chi nhánh đó - thực sự là một lịch sử thực sự của chi nhánh đó. Mặt khác, nó không rõ ràng với tôi khi xem qua nhật ký xem các xác nhận có ở trên my_experimentsnhánh hay không.

Có cách nào để làm điều này với Git?

Câu trả lời:


139

Bạn có thể sử dụng một phạm vi để làm điều đó.

git log master..

Nếu bạn đã kiểm tra my_experimentchi nhánh của bạn . Điều này sẽ so sánh nơi masterđang ở HEAD(đầu của my_experiment).


3
Ok nói quá sớm. Điều đó đã làm điều đó cho ví dụ đơn giản của tôi. Nhưng bây giờ tôi đang nhìn vào repo thực sự của người khác và tôi nhận ra rằng để sử dụng lệnh này đúng cách, tôi cần phải biết nhánh nào mà nhánh hiện tại của tôi được tạo ra. Có lẽ tôi có thể nói điều này từ gitk nhưng nó không rõ ràng đối với tôi. Có suy nghĩ gì không?
Marplesoft

@Marplesoft Có thể phức tạp để tìm ra điều đó. Xem câu hỏi này .
alex

Bạn có thể giải thích ngắn gọn làm thế nào nó hoạt động? Điều gì git log master..nói với Git?
tonix

2
@tonix Theo liên kết trong câu trả lời để biết thêm thông tin về cách một phạm vi hoạt động (phần master..).
alex

7

Các git merge-baselệnh có thể được sử dụng để tìm một tổ tiên chung. Vì vậy, nếu my_experiment chưa được hợp nhất thành master và my_experiment được tạo từ master, bạn có thể:

git log --oneline `git merge-base my_experiment master`..my_experiment

Nếu bạn muốn bao gồm cha mẹ của cam kết đầu tiên của mình, hãy thêm ^--first-Parent : git log --oneline `git merge-base my_experiment master`^..my_experiment --first-parent
Eric Lavoie

7

Lưu ý: nếu bạn giới hạn nhật ký đó ở lần cam kết cuối cùng (ví dụ 3 lần xác nhận cuối cùng, git log -3), hãy đảm bảo đặt khoảng trắng giữa 'n' và chi nhánh của bạn:

git log -3 master..

Trước Git 2.1 (tháng 8 năm 2014), lỗi này: git log -3master..thực sự sẽ hiển thị cho bạn 3 lần xác nhận cuối cùng của chi nhánh hiện tại (ở đây my_experiment), bỏ qua mastergiới hạn (nghĩa là nếu my_experimentchỉ chứa một cam kết, 3 vẫn sẽ được liệt kê, 2 trong số đó từ master)

Xem cam kết e3fa568 của Junio ​​C Hamano ( gitster) :

sửa đổi: phân tích " git log -<count>" cẩn thận hơn

Dòng lệnh bị nhập sai này chỉ đơn giản là bỏ qua " master" và kết thúc hiển thị hai lần xác nhận từ hiện tại HEAD:

$ git log -2master

bởi vì chúng tôi cung cấp " 2master" cho atoi()mà không đảm bảo rằng toàn bộ chuỗi được phân tích cú pháp dưới dạng một số nguyên.

Sử dụng strtol_i()chức năng trợ giúp thay thế.


1

Bạn chỉ có thể sử dụng git log --oneline


Mặc dù mã này có thể trả lời câu hỏi, việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời.
DebanjanB

1

Tôi nghĩ rằng một lựa chọn cho mục đích của bạn là git log --online --decorate. Điều này cho bạn biết cam kết đã kiểm tra và các cam kết hàng đầu cho từng nhánh mà bạn có trong câu chuyện của mình. Bằng cách này, bạn có một cái nhìn tốt đẹp về cấu trúc của repo của bạn và các cam kết liên quan đến một chi nhánh cụ thể. Tôi nghĩ rằng đọc điều này có thể giúp đỡ.


0

Tôi biết rằng đã rất muộn cho cái này ... Nhưng đây là một oneliner (không đơn giản) để có được thứ bạn đang tìm kiếm:

git show-branch --all 2>/dev/null | grep -E "\[$(git branch | grep -E '^\*' | awk '{ printf $2 }')" | tail -n+2 | sed -E "s/^[^\[]*?\[/[/"
  • Chúng tôi đang liệt kê các cam kết với tên chi nhánh và vị trí tương đối cho các trạng thái chi nhánh thực tế với git show-branch(gửi cảnh báo tới /dev/null).
  • Sau đó, chúng tôi chỉ giữ những người có tên chi nhánh của chúng tôi trong khung với grep -E "\[$BRANCH_NAME".
  • Trường hợp thực tế $BRANCH_NAMEthu được với git branch | grep -E '^\*' | awk '{ printf $2 }'(nhánh có một ngôi sao, lặp lại mà không có ngôi sao đó).
  • Từ kết quả của chúng tôi, chúng tôi loại bỏ dòng dự phòng lúc đầu bằng tail -n+2.
  • Và sau đó, chúng tôi fianlly dọn dẹp đầu ra bằng cách loại bỏ tất cả mọi thứ trước [$BRANCH_NAME]với sed -E "s/^[^\[]*?\[/[/".
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.