2012-03-30 31 views
71

Tôi đã xem xét và không chắc chắn liệu điều này có thể thực hiện được không, nhưng tại đây:Git: Hiển thị tất cả các thay đổi khác nhau cho một dòng trong một tệp được chỉ định trong toàn bộ lịch sử git

Tôi có (javascript) tập tin (nói /lib/client.js) trong đó tôi có một định danh duy nhất được gán cho một biến, như vậy: var identifier = "SOME_IDENTIFIER";

Bạn có thể nghĩ về nhận dạng giống như một số phiên bản: Theo định kỳ, chúng tôi sẽ thay đổi biến này thành một số nhận dạng mới.

Điều tôi muốn làm là tìm tất cả số nhận dạng duy nhất mà chúng tôi từng sử dụng. Làm thế nào tôi có thể làm điều này với git?

Tôi tưởng tượng có thể có một cách để tìm kiếm thông qua lịch sử git và in dòng phù hợp với "var identifier =". Tôi có thể loại bỏ danh sách này theo cách thủ công.

Dù sao, tôi đánh giá cao bất kỳ thông tin chi tiết nào ở đây. Cảm ơn.

+2

bản sao có thể có của [Truy xuất nhật ký cam kết cho một dòng cụ thể trong một tệp?] (Http://stackoverflow.com/questions/8435343/retrieve-the-commit-log-for-a-specific-line-in -a-file) –

Trả lời

37

Xem trang hướng dẫn cho git-loggitdiffcore. Tôi tin rằng lệnh này sẽ làm điều đó, nhưng nó có thể không hoàn toàn đúng:

git log -G "var identifier =" file.js 

EDIT: Dưới đây là một khởi đầu khó khăn cho một kịch bản bash để hiển thị các dòng thực tế. Đây có thể là những gì bạn đang tìm kiếm.

for c in $(git log -G "something" --format=%H -- file.js); do 
    git --no-pager grep -e "something" $c -- file.js 
done 

Nó sử dụng git log -G để tìm các cam kết thú vị, sử dụng --format=%H để tạo ra một danh sách các cam kết băm. Sau đó nó lặp lại trên mỗi cam kết thú vị, yêu cầu git grep để hiển thị các dòng từ cam kết và tệp có chứa regex, được bắt đầu bằng băm cam kết.


EDIT: Thay đổi để sử dụng -G thay vì -S như đề xuất trong ý kiến.

+0

@Rob - cảm ơn vì điều này - chỉnh sửa nhỏ cho tập lệnh của bạn - chỉ đặt tên tệp chỉ hiển thị các cam kết chỉ ảnh hưởng đến tệp đó - nếu cam kết tham chiếu các tệp khác không được liệt kê –

+0

@AdrianCornish - Rất vui được Hữu ích. Tôi nghĩ rằng OP muốn chỉ xem xét một tệp, nhưng bạn hoàn toàn chính xác rằng việc xóa tên tệp có lẽ là một tập lệnh hữu ích hơn. – rob

+0

Tôi có một tình huống khó khăn hơn. Tệp được đề cập được chuyển từ tệp paht_a/sang tệp path_b /. Bây giờ khi tôi làm điều đó trong path_b nó chỉ hiển thị thay đổi lên đến khi tập tin di chuyển từ path_a đến path_b. Nếu tôi làm điều đó trong path_a nó cho tôi biết gây tử vong: đối số mơ hồ 'tập tin': bản sửa đổi không rõ hoặc đường dẫn không có trong cây đang hoạt động. –

12

Bạn cũng có thể làm điều này với gitk:

gitk file.js 

Trong "cam kết" thả xuống, chọn "thêm/gỡ bỏ chuỗi:" và trong hộp văn bản bên cạnh nó, nhập "var nhận dạng =" và bất kỳ cam kết nào thêm hoặc xóa các dòng có chứa chuỗi đó sẽ được đánh dấu.

+0

Điều này đã giúp xác định cam kết mà tại đó dòng có chứa "var identifier =" đã được thêm vào, nhưng nó không hiển thị các cam kết tiếp theo đã sửa đổi dòng này. – findchris

+2

Bạn đã thử 'git blame file.js' hoặc' git gui đổ lỗi cho file.js' chưa? –

+0

Tôi biết những gì git đổ lỗi; Tôi đang tìm kiếm một lịch sử đầy đủ các bản sửa đổi, không phải là một khác biệt duy nhất. – findchris

6

Nếu bạn thích ứng @ câu trả lời cướp của chỉ một chút, git log sẽ cơ bản làm việc này cho bạn, nếu tất cả bạn cần là một so sánh trực quan:

git log -U0 -S "var identifier =" path/to/file 

-U0 nghĩa sản lượng trong chế độ bản vá (-p), và hiển thị không có dòng ngữ cảnh xung quanh bản vá.

Bạn thậm chí có thể làm điều này qua các chi nhánh:

git log -U0 -S "var identifier =" branchname1 branchname2 -- path/to/file 

Có thể có một cách để ngăn chặn những tiêu đề khác, nhưng tôi không biết của ai.

+0

Làm việc cho tôi! Cảm ơn. –

54

Kể từ git 1.8.4, có một cách trực tiếp hơn để trả lời câu hỏi của bạn.

Giả sử rằng dòng 110 là dòng nói var identifier = "SOME_IDENTIFIER";, sau đó làm điều này:

git log -L110,110:/lib/client.js 

này sẽ trở lại mỗi cam kết mà đụng rằng dòng mã.

[Git Documentation (xem phần "-L" dòng paramenter lệnh)]

2

Trong magit, bạn có thể làm điều này với

l, =L 

Sau đó nó sẽ yêu cầu bạn cho file và bắt đầu, dòng kết thúc.

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