git: Làm thế nào để khác biệt các tệp đã thay đổi so với các phiên bản trước sau một lần kéo?


117

Khi tôi chạy "git pull", tôi thường muốn biết những gì đã thay đổi giữa phiên bản cuối cùng của tệp và phiên bản mới. Giả sử tôi muốn biết người khác đã cam kết những gì đối với một tệp cụ thể.

Điều đó được thực hiện như thế nào?

Tôi giả sử đó là "git diff" với một số tham số cho cam kết x so với cam kết y nhưng dường như tôi không thể hiểu được cú pháp. Tôi cũng thấy "git log" hơi khó hiểu và không chắc chắn nơi lấy ID cam kết của phiên bản tệp mới nhất của tôi so với phiên bản mới.


1
Bạn có thể tìm thấy công cụ đồ họa gitk phù hợp với sở thích của mình hơn.
crazyscot

stackoverflow.com/questions/61002/… có thể tương tự với cái này
VonC

Câu trả lời:


158

Có tất cả các cách tuyệt vời để chỉ định cam kết - hãy xem phần chỉ định bản sửa đổi của man git-rev-parseđể biết thêm chi tiết. Trong trường hợp này, bạn có thể muốn:

git diff HEAD@{1}

@{1}nghĩa là "vị trí trước đó của tham chiếu mà tôi đã chỉ định", để đánh giá những gì bạn đã kiểm tra trước đó - ngay trước khi kéo. Bạn có thể giải quyết HEADở phần cuối ở đó nếu bạn cũng có một số thay đổi trong cây công việc của mình và bạn không muốn thấy sự khác biệt của chúng.

Tôi không chắc bạn đang yêu cầu gì với "ID cam kết của phiên bản tệp mới nhất của tôi" - "ID" cam kết (SHA1 hash) là hex 40 ký tự nằm ngay đầu mỗi mục nhập trong đầu ra của git log. Đó là hàm băm cho toàn bộ cam kết, không phải cho một tệp nhất định. Bạn không thực sự cần nhiều hơn - nếu bạn muốn chỉ khác một tệp trong quá trình kéo, hãy làm

git diff HEAD@{1} filename

Đây là một điều chung chung - nếu bạn muốn biết về trạng thái của tệp trong một cam kết nhất định, bạn chỉ định cam kết và tệp, không phải một ID / băm cụ thể cho tệp.


Bài đăng trước được liên kết của VonC nói về cơ bản giống như điều này, nhưng lời giải thích hơi khác, vì vậy tôi sẽ để lại điều này ngay bây giờ. (Nó cũng sử dụng @{1}như một cách viết tắt cho HEAD@{1})
Cascabel

đúng, nhưng tôi cũng thích lời giải thích. +1
VonC

Đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn đã giải thích.
lucapette

+1 cho những gì tôi đã tìm kiếm trên Google. Sẽ là tuyệt vời nếu điều này được bình chọn là câu trả lời và tình cờ gặp lại đầu trang ... :)
Longda

@longda Nếu bạn đang sắp xếp theo phiếu bầu (mà tôi nghĩ là mặc định) thì nó phải ở trên cùng.
Cascabel

57

Tôi thích sử dụng:

git diff HEAD^

Hoặc nếu tôi chỉ muốn khác một tệp cụ thể:

git diff HEAD^ -- /foo/bar/baz.txt

5
-1: HEAD^là cam kết gốc, không phải cam kết trướcpull
CharlesB

1
Nếu HEADlà một cam kết hợp nhất, HEAD^là cam kết mẹ đầu tiên, vì vậy có, nó có thể là cam kết trước pull. Để có được phụ huynh khác (đối với hợp nhất hai chiều), hãy sử dụng HEAD^2. Nhưng sau đó, câu trả lời ở trên là không thực sự trả lời câu hỏi ở nơi đầu tiên, vì vậy bỏ -1 ;-)
Michael hoang dã

Cảm ơn bạn đã làm rõ. Tôi đã không đọc kỹ câu hỏi, vì tôi đang tìm kiếm thứ khác và liên kết này xuất hiện cao trên trang kết quả. Tôi đã nghĩ rằng mình sẽ tham gia vì tôi là người dùng mới và không có bất kỳ nghiệp nào (nếu đó là những gì nó được gọi trên SO). Lỗi của tôi =)
cadizm

3
@MichaelWild nó có thể không phải là những gì người hỏi đang hỏi, nhưng đó là những gì tôi đang tìm kiếm khi tôi tìm thấy điều này. Nó rất hữu ích cho tôi. Đang ủng hộ.
John Dvorak

Đây là những gì TortoiseGit "Khác biệt với phiên bản trước" làm. Và đó là những gì tôi đang tìm kiếm.
Fabien Haddadi

15

Nếu bạn làm thẳng git pullthì bạn sẽ được 'tua đi nhanh' hoặc hợp nhất một số lượng cam kết không xác định từ kho lưu trữ từ xa. Tuy nhiên, điều này xảy ra như một hành động, vì vậy cam kết cuối cùng mà bạn đã ở ngay trước khi kéo sẽ là mục nhập cuối cùng trong bản tóm tắt và có thể được truy cập dưới dạng HEAD@{1}. Điều này có nghĩa là bạn có thể làm:

git diff HEAD@{1}

Tuy nhiên, tôi thực sự khuyên bạn rằng nếu đây là điều bạn thấy mình đang làm rất nhiều thì bạn nên xem xét việc chỉ thực hiện git fetchvà kiểm tra nhánh đã tìm nạp trước khi hợp nhất hoặc khôi phục theo cách thủ công. Ví dụ: nếu bạn đang ở chế độ master và định kéo về origin / master:

git fetch

git log HEAD..origin/master

 # looks good, lets merge

git merge origin/master

Sử dụng tốt git logthay vì git diffở đây (ngay cả khi cú pháp hơi không nhất quán giữa '..' for git logvà '...' for git diff;) +1 Xem stackoverflow.com/questions/53569/…stackoverflow.com/questions / 850607 /…
VonC

May mắn thay nếu bạn sử dụng cú pháp '..' trong lệnh git diff, git "làm đúng".
CB Bailey
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.