git diff file terhadap perubahan terakhirnya

236

Apakah mungkin untuk mendapatkan git untuk menghasilkan perbedaan antara file tertentu seperti yang ada sekarang, dan seperti yang ada sebelum komit terakhir yang mengubahnya?

Yaitu, jika kita tahu:

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

Kemudian git diff 456def myfiletunjukkan perubahan terakhir ke myfile. Apakah mungkin untuk melakukan hal yang sama tanpa pengetahuan yang dihasilkan oleh git log; apa yang berubah di 123abc?

Chowlett
sumber
8
Saya lebih suka menggunakangit diff HEAD^ <file_path>
asgs
4
@ asgs - Tidak melakukan apa yang saya minta (karena dua alasan - HEAD^adalah 123abc, HEAD^^adalah 456def; dan jika ada komitmen lain yang tidak memengaruhi file ini maka HEAD^merujuk pada mereka)
Chowlett
Anda benar, melewatkan bagian "komit terakhir yang mengubahnya"
asgs

Jawaban:

215

Ini memang ada, tetapi sebenarnya fitur git log:

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

Catatan yang -pjuga dapat digunakan untuk menampilkan diff sebaris dari komit tunggal:

git log -p -1 <commit>

Opsi yang digunakan:

  • -p(juga -uatau --patch) disembunyikan deeeeeeeep di git-loghalaman manual, dan sebenarnya merupakan opsi tampilan untuk git-diff. Ketika digunakan dengan log, itu menunjukkan tambalan yang akan dihasilkan untuk setiap komit , bersama dengan informasi komit - dan menyembunyikan komit yang tidak menyentuh yang ditentukan <path>. (Perilaku ini dijelaskan dalam paragraf di --full-diff, yang menyebabkan perbedaan penuh dari setiap komit ditampilkan).
  • -1hanya menunjukkan perubahan terbaru ke file yang ditentukan ( -n 1dapat digunakan sebagai ganti -1); jika tidak, semua perbedaan yang tidak nol dari file tersebut ditampilkan.
  • --follow diperlukan untuk melihat perubahan yang terjadi sebelum mengganti nama.

Sejauh yang saya tahu, ini adalah satu-satunya cara untuk segera melihat set perubahan terakhir yang dibuat untuk file tanpa menggunakan git log(atau serupa) untuk menghitung jumlah revisi intervensi atau menentukan hash dari komit.

Untuk melihat perubahan revisi yang lebih lama, cukup gulir ke seluruh log, atau tentukan komit atau tag untuk memulai log. (Tentu saja, menentukan komit atau tag mengembalikan Anda ke masalah awal untuk mengetahui apa komit atau tag yang benar.)

Kredit yang harus dibayar:

  • Saya menemukan log -pberkat jawaban ini .
  • Penghargaan untuk FranciscoPuga dan jawaban ini untuk menunjukkan saya --followpilihan.
  • Penghargaan untuk ChrisBetti untuk menyebutkan -n 1opsi dan atatko untuk menyebutkan -1varian.
  • Penghargaan untuk sweaver2112 karena membuat saya benar-benar membaca dokumentasi dan mencari tahu apa -p"arti" secara semantik.
Kyle Strand
sumber
6
Ini solusi yang bagus untuk saya. Menunjukkan setiap komit dan perbedaannya ke file saat ini ketika saya berlarigit log -p filename
Ian Jamieson
4
Sempurna. Untuk melihat perubahan terakhir, sesederhana menambahkan -n 1parameter. git log -p -n 1 filename
Chris Betti
@ ChrisBetti Terima kasih; Saya telah memasukkan itu ke dalam jawaban saya!
Kyle Strand
1
-n 1juga dapat diganti dengan -1, itu tidak mengubah hasil. Saya hanya lebih menyukai sintaks:git log -p -1 filename
atatko
1
ada opsi yang berguna "--skip = [n]". Anda dapat mengetik git log -p -1 --skip=1 <path>untuk menampilkan komit kedua.
Maciek Łoziński
220

Salah satu cara untuk menggunakan git diff adalah:

git diff <commit> <path>

Dan cara yang umum untuk merujuk satu commit dari commit terakhir adalah sebagai jalur relatif ke HEAD yang sebenarnya. Anda dapat merujuk komit sebelumnya sebagai HEAD ^ (dalam contoh Anda ini akan menjadi 123abc) atau HEAD ^^ (456def dalam contoh Anda), dll ...

Jadi jawaban untuk pertanyaan Anda adalah:

git diff HEAD^^ myfile
Francisco Puga
sumber
6
Oh tentu. Saya mencoba HEAD^, tetapi tentu saja itu tidak menghasilkan apa-apa. Tidak berpikir untuk mencoba HEAD^^.
Chowlett
17
Mungkin sintaks yang lebih mudah untuk komit lama:HEAD~2
ibizaman
19
Tidak benar (setidaknya untuk Git 1.9.0) yang HEAD^^ myfilebenar-benar akan merujuk pada komitmen kedua-ke-terakhir yang diubah myfile; itu akan merujuk pada komitmen kedua-ke-terakhir secara keseluruhan. Apakah ada cara untuk menentukan "Saya ingin melihat perubahan terakhir yang dibuat untuk file ini" tanpa menentukan (bagian dari) hash komit atau menghitung jumlah komit antara perubahan terakhir yang dibuat untuk file itu dan revisi saat ini?
Kyle Strand
3
Hm, sepertinya git log -pcukup dekat.
Kyle Strand
30
alasan downvote: pertanyaan bertanya "antara file tertentu seperti yang ada sekarang, dan seperti yang ada sebelum komit terakhir yang mengubahnya ", tetapi jika file tidak diubah dalam komit keseluruhan terakhir, jawaban ini tidak berfungsi.
Chris Betti
8

Jika Anda baik-baik saja menggunakan alat grafis ini berfungsi dengan sangat baik:

gitk <file>

gitk sekarang menunjukkan semua komit di mana file telah diperbarui. Menandai komit akan menunjukkan perbedaan terhadap komit sebelumnya dalam daftar. Ini juga berfungsi untuk direktori, tetapi kemudian Anda juga bisa memilih file untuk diff untuk komit yang dipilih. Sangat berguna!

Martin G
sumber
1
Juga sangat berguna: git difftool HEAD^ fileataugit difftool -d HEAD^ path
ForeverLearning