git diff tập tin chống lại sự thay đổi cuối cùng của nó


236

Có thể có được git để tạo ra một sự khác biệt giữa một tệp cụ thể như nó tồn tại bây giờ và như nó tồn tại trước khi cam kết cuối cùng đã thay đổi nó?

Đó là, nếu chúng ta biết:

$ git log --oneline myfile
123abc Fix some stuff
456def Frobble the foos
789dba Initial commit

Sau đó git diff 456def myfilecho thấy sự thay đổi cuối cùng đối với myfile. Có thể làm tương tự mà không có kiến ​​thức được tạo ra bởi git log; Điều gì đã thay đổi trong 123abc?


8
Tôi thích sử dụnggit diff HEAD^ <file_path>
asg

4
@asgs - không làm những gì tôi đã được hỏi (vì hai lý do - HEAD^được 123abc, HEAD^^456def, và nếu có những cam kết khác mà không ảnh hưởng đến tập tin này sau đó HEAD^đề cập đến họ)
Chowlett

Bạn nói đúng, đã bỏ lỡ phần "cam kết cuối cùng đã thay đổi nó"
vào

Câu trả lời:


215

Điều này không tồn tại, nhưng nó thực sự là một tính năng của git log:

git log -p [--follow] [-1] <path>

Lưu ý rằng -pcũng có thể được sử dụng để hiển thị khác biệt nội tuyến từ một cam kết duy nhất:

git log -p -1 <commit>

Tùy chọn được sử dụng:

  • -p(cũng -uhoặc --patch) được ẩn deeeeeeeep trong git-logtrang man và thực sự là một tùy chọn hiển thị cho git-diff. Khi được sử dụng log, nó hiển thị các bản vá sẽ được tạo cho mỗi lần xác nhận , cùng với thông tin cam kết, và ẩn các cam kết không chạm vào chỉ định <path>. (Hành vi này được mô tả trong đoạn trên --full-diff, điều này gây ra sự khác biệt đầy đủ của từng cam kết được hiển thị.)
  • -1chỉ hiển thị thay đổi gần đây nhất đối với tệp được chỉ định ( -n 1có thể được sử dụng thay vì -1); mặt khác, tất cả các khác không khác không của tập tin đó được hiển thị.
  • --follow được yêu cầu để xem các thay đổi xảy ra trước khi đổi tên.

Theo như tôi có thể nói, đây là cách duy nhất để thấy ngay bộ thay đổi cuối cùng được thực hiện cho một tệp mà không sử dụng git log(hoặc tương tự) để đếm số lần sửa đổi can thiệp hoặc xác định hàm băm của cam kết.

Để xem các thay đổi sửa đổi cũ hơn, chỉ cần cuộn qua nhật ký hoặc chỉ định một cam kết hoặc thẻ để bắt đầu nhật ký. (Tất nhiên, việc chỉ định một cam kết hoặc thẻ đưa bạn trở lại vấn đề ban đầu để tìm ra cam kết hoặc thẻ chính xác là gì.)

Tín dụng có tín dụng đến hạn:

  • Tôi phát hiện ra log -pnhờ câu trả lời này .
  • Tín dụng cho FranciscoPuga và câu trả lời này cho tôi thấy --followtùy chọn.
  • Tín dụng cho ChrisBetti khi đề cập đến -n 1tùy chọn và atatko khi đề cập đến -1biến thể.
  • Tín dụng cho sweaver2112 để giúp tôi thực sự đọc tài liệu và tìm hiểu -p"nghĩa là" về mặt ngữ nghĩa.

6
Đây là một giải pháp tuyệt vời cho tôi. Hiển thị từng cam kết và sự khác biệt của nó với tệp hiện tại khi tôi chạygit log -p filename
Ian Jamieson

4
Hoàn hảo. Để xem chỉ thay đổi cuối cùng, đơn giản như thêm -n 1tham số. git log -p -n 1 filename
Chris Betti

@ChrisBetti Cảm ơn; Tôi đã kết hợp nó vào câu trả lời của tôi!
Kyle Strand

1
-n 1cũng có thể được thay thế bởi -1, nó không thay đổi kết quả Tôi chỉ thích cú pháp:git log -p -1 filename
atatko

1
có một tùy chọn hữu ích "--skip = [n]". Bạn có thể gõ git log -p -1 --skip=1 <path>để hiển thị cam kết thứ hai.
Maciek Łoziński

220

Một trong những cách sử dụng git diff là:

git diff <commit> <path>

Và một cách phổ biến để giới thiệu một cam kết của lần cam kết cuối cùng là một đường dẫn tương đối đến ĐẦU thực tế. Bạn có thể tham khảo các cam kết trước đó là CHÍNH ^ (trong ví dụ của bạn, đây sẽ là 123abc) hoặc CHÍNH ^^ (456def trong ví dụ của bạn), v.v ...

Vì vậy, câu trả lời cho câu hỏi của bạn là:

git diff HEAD^^ myfile

6
Ồ dĩ nhiên rồi. Tôi đã cố gắng HEAD^, nhưng tất nhiên điều đó không tạo ra gì. Không nghĩ sẽ thử HEAD^^.
Chowlett

17
Có thể cú pháp dễ dàng hơn cho các cam kết từ lâu:HEAD~2
ibizaman

19
Điều đó không đúng (ít nhất là đối với Git 1.9.0) HEAD^^ myfilethực sự sẽ đề cập đến cam kết thứ hai đến cuối cùng đã thay đổi myfile; nó sẽ đề cập đến cam kết thứ hai đến cuối cùng. Có cách nào để chỉ định "Tôi muốn xem thay đổi cuối cùng được thực hiện cho tệp này" mà không chỉ định (một phần) hàm băm cam kết hoặc đếm số lần xác nhận giữa thay đổi cuối cùng được thực hiện cho tệp đó và sửa đổi hiện tại không?
Kyle Strand

3
Hừm, hình như git log -plà khá gần.
Kyle Strand

30
Lý do downvote: câu hỏi hỏi "giữa một tệp cụ thể như hiện tại và như nó tồn tại trước lần cam kết cuối cùng đã thay đổi nó ", nhưng nếu tệp không bị thay đổi trong lần xác nhận chung cuối cùng, câu trả lời này không hoạt động.
Chris Betti

8

Nếu bạn ổn khi sử dụng một công cụ đồ họa thì nó hoạt động rất tốt:

gitk <file>

gitk hiện hiển thị tất cả các xác nhận nơi tệp đã được cập nhật. Đánh dấu một cam kết sẽ cho bạn thấy sự khác biệt so với các cam kết trước đó trong danh sách. Điều này cũng hoạt động cho các thư mục, nhưng sau đó bạn cũng có thể chọn tệp khác cho cam kết đã chọn. Siêu hữu ích!


1
Cũng rất hữu ích: git difftool HEAD^ filehoặcgit difftool -d HEAD^ path
ForeverLearning
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.