2011-01-24 36 views
102

Tôi muốn tìm cam kết gần đây nhất đã sửa đổi tệp nguồn.Làm cách nào để tìm thấy cam kết git gần đây nhất đã sửa đổi tệp?

Tôi có thể sử dụng git blame để xem tất cả các ngày cho cam kết theo từng dòng, nhưng thật khó để biết chính xác cam kết nào là lần cuối cùng chạm vào tệp.

Làm cách nào tôi có thể tìm thấy cam kết cuối cùng đã chạm vào một tệp nhất định trong kho lưu trữ git của tôi?

Trả lời

122

git log hỗ trợ nhìn vào lịch sử của tác cụ thể (và thư mục), do đó bạn có thể viết này:

git log my/file.c 

Nếu bạn thực sự chỉ muốn liệt kê cam kết một gần đây nhất, ví dụ như sử dụng nó trong một kịch bản, bạn có thể sử dụng -n 1:

git log -n 1 --pretty=format:%H -- my/file.c 

--pretty=format:%h nói git log để chỉ hiển thị các cam kết băm (nhờ vào sự TheBamf). Trình tách phân cách -- dừng tên tệp khỏi việc diễn giải dưới dạng tên cam kết, chỉ trong trường hợp nó không rõ ràng.

+4

Nếu bạn muốn biết lần cuối tệp được sửa đổi bất kể nhánh nào, bạn có thể xem xét tất cả các nhánh bằng cách thêm tùy chọn '--all'. –

8

Tôi không chắc chắn nếu đây là những gì bạn muốn nhưng nếu bạn làm một git log <thefile> để có được các cam kết thay đổi tập tin đó. Bạn có thể chọn một trên cùng. Nó sẽ là một trong những bạn đang tìm kiếm.

+3

nếu bạn sử dụng 'git log -n1 - ' (hoặc đặt đầu ra thành 'đầu -1' nếu bạn muốn lãng phí tài nguyên), bạn không cần phải chọn dòng trên cùng (xem Jo Liss [answer] (http://stackoverflow.com/questions/4784575/how-do-i-find-the-most-recent-git-commit-that-modified-a-file/4784629#4784629)) –

+3

Điểm tốt. Tôi nghĩ bạn cũng có thể bỏ qua '-n' và sử dụng' -1' trực tiếp. –

1

Khi bạn có id SHA của cam kết bạn muốn xem bằng cách sử dụng git log FILENAME, bạn sẽ có thể thực hiện git show SHA_ID_HERE để xem những gì bạn đã làm cho cam kết cụ thể đó. Bạn thậm chí không cần nhập toàn bộ ID; 6 ký tự đầu tiên là đủ.

+3

nhiều hơn một chút so với OP được yêu cầu, nhưng FYI bạn có thể kết hợp thành một lớp lót: 'git show $ (git log -1 --pretty ="% H "- FILENAME)' –

+0

Ah yes, đó là dễ dàng hơn. Cảm ơn vì tiền hỗ trợ. – Joe

0

để có được chỉ là ref trên cùng một dòng, hãy thử:

git log -n1 --oneline <path> | awk '{print $1;}' 
25

Nếu bạn muốn chỉ nhận được các hash của mới nhất cam kết sửa đổi một tập hợp cụ thể của tập tin (và muốn tránh awk), bạn có thể sử dụng:

git log -n 1 --pretty=format:%h -- <path> 

này có thể hữu ích cho việc băm cam kết cho sau đó sử dụng với git describe.

Ví dụ (trong trường hợp nó rất hữu ích cho bất cứ ai) ...

tôi tạo ra một phiên bản id hiện tại bằng cách xem xét mới nhất cam kết thay đổi bất kỳ tập tin nguồn (giả sử bạn đánh dấu phiên bản với các thẻ như mycode-1.2.1):

COMMIT=$(git log -n 1 --pretty=format:%h -- *.c *.h) 
if VN=$(git describe --always --abbrev=5 --match "mycode-*" $COMMIT 2>/dev/null) && 
case "$VN" in 
mycode-*) 
    git update-index -q --refresh 
    test -z "$(git diff-index --name-only HEAD *.c *.h)" || 
    VN="$VN-mod" ;; 
*) VN="mycode-unknown-g$VN" ;; 
esac 
then 
    continue 
else 
VN="mycode-unknown" 
fi 

này tạo id như:

  • mycode-1.2.1 - khi trạng thái hiện tại của thứ e file nguồn tương ứng với một phiên bản được gắn thẻ
  • mycode-1.2.1-g3k7s2 - khi trạng thái hiện tại của các tập tin nguồn tương ứng với cam kết sau một phiên bản được gắn thẻ
  • mycode-1.2.1-g3k7s2-mod - khi trạng thái hiện tại của các file nguồn đã được sửa đổi kể từ khi cam kết cuối cùng sau một phiên bản gắn thẻ
  • mycode-unknown - khi đến nay vẫn chưa được một thẻ phiên bản tạo
+3

'$ VN' trông giống như một số loại SVN cơn ác mộng – ThorSummoner

18

Nếu bạn chỉ muốn tìm commit mới nhất, bạn không muốn git-log, bạn muốn git-rev-list, liệt kê các đối tượng cam kết thay đổi tệp đó, trong đường dẫn cam kết đó, bắt đầu bằng tệp gần đây nhất (theo thứ tự thời gian). Một cách đơn giản:

git rev-list -1 <commit> <filename>

Đối git-rev-list trong trường hợp của bạn, bạn chỉ cần cung cấp:

  • Số lượng cam kết để bao gồm, hoặc -1 chỉ gần đây nhất,
  • Các chi nhánh (hoặc id cam kết) để bắt đầu nhìn lại từ, HEAD nếu bạn đã ở trên đó hoặc --all nếu bạn muốn tất cả các cam kết đã biết và
  • Đường dẫn tương đối vào tệp của bạn.

này chỉ trả về gần đây nhất cam kết ID tại các chi nhánh hiện tại để thay đổi tập tin đó, ví dụ: 215095e2e338525be0baeeebdf66bfbb304e7270

Đối với một ví dụ phức tạp hơn, bạn có thể sử dụng tên thẻ, và thậm chí cả tài liệu tham khảo từ xa, và bao gồm tương đối tên đường dẫn với các kí hiệu, cho ví dụ:

git rev-list origin/user/bob/testbranch -1 src/bfiles/*.txt

... trong đó sẽ cho bạn biết sự thay đổi gần đây nhất là trận đấu wildcard trong lịch sử của ngành đó. Các tùy chọn cho danh sách rev là cực đoan, nó là một trong những lệnh hệ thống ống nước quan trọng nhất, vì vậy bạn có thể bao gồm hoặc loại trừ bằng bất kỳ tiêu chí nào bạn có thể tưởng tượng.

Tất nhiên, hãy tham khảo git-rev-list(1) Manual Page.

+0

Bạn thực sự không giải thích tại sao sử dụng' git-log' là kém hơn. –

+3

Tôi sẽ không nói kém hơn, chỉ là nó cung cấp thông tin không liên quan theo mặc định. git-rev-list chỉ trả về ID cam kết, đó là những gì bạn muốn nếu bạn định nạp phản hồi vào một tập lệnh hoặc quá trình tự động hóa khác. git-log trả về thông tin về các cam kết đã chọn, đầu tiên bằng cách sử dụng git-rev-list để thu thập các thẻ cam kết, sau đó thu thập thông tin trên mỗi cam kết. Nếu bạn chỉ cần lọc ra thông tin cam kết và sử dụng các id, thì bạn chỉ có thể sử dụng git-rev-list ở vị trí đầu tiên. Vì nhật ký dựa trên danh sách rev, nên hầu hết các thông số bộ lọc giống nhau. –

+1

'git-log' là sứ,' git-rev-list' là hệ thống ống nước. – blitzen9872

Các vấn đề liên quan