Git berbeda antara cabang dan master saat ini, tetapi tidak termasuk komit yang tidak dimutakhirkan

171

Saya ingin perbedaan semua perubahan di cabang yang belum digabungkan untuk dikuasai.

Saya mencoba:

git diff master
git diff branch..master
git diff branch...master

Namun, dalam setiap kasus ini diff berisi konten master yang belum digabungkan ke cabang saya.

Apakah ada cara untuk melakukan perbedaan antara cabang dan master saya yang mengecualikan perubahan master yang belum digabung ke cabang saya?

pillarOfLight
sumber
9
Jika Anda flip sekitar versi kedua, Anda mendapatkan apa yang Anda inginkan: git diff master..branch. Anda dapat mempersingkat git diff master..jika Anda berada di cabang. The r1..r2sintaks adalah singkatan ^r1 r2yang berarti "menunjukkan segala sesuatu yang turun dari r2dan tidak dicapai dari r1". git help gitrevisionsmemiliki informasi tentang berbagai sintaks yang dapat Anda gunakan.
John Szakmeister
1
Saya memperluas jawaban saya setelah saya membaca lebih lanjut tentang ...sintaksis git diff. Komentar Anda salah, @ jszakmeister, karena rentang revisi seperti yang dijelaskan gitrevisionstidak ada hubungannya dengan git diff. Diff membandingkan dua poin dalam sejarah, tidak dapat bekerja dengan rentang.
Palec
Anda benar. Saya selalu lupa bahwa itu git diffbekerja secara berbeda dari perintah lain ... sebuah fakta yang menurut saya membuat frustrasi. :-(
John Szakmeister
pastikan bahwa Anda memperbarui salinan master lokal sebelum membandingkan
joe

Jawaban:

232
git diff `git merge-base master branch`..branch

Gabung basis adalah titik di mana branchmenyimpang dari master.

Git diff mendukung sintaks khusus untuk ini:

git diff master...branch

Anda tidak boleh menukar sisi karena Anda akan mendapatkan cabang lainnya. Anda ingin tahu apa yang berubah branchkarena itu menyimpang dari master, bukan sebaliknya.

Terkait longgar:


Perhatikan bahwa ..dan ...sintaksis tidak memiliki semantik yang sama seperti pada alat Git lainnya. Ini berbeda dari makna yang ditentukan dalam man gitrevisions.

mengutip man git-diff:

  • git diff [--options] <commit> <commit> [--] [<path>…]

    Ini untuk melihat perubahan antara dua arbitrer <commit>.

  • git diff [--options] <commit>..<commit> [--] [<path>…]

    Ini identik dengan formulir sebelumnya. Jika <commit>di satu sisi dihilangkan, itu akan memiliki efek yang sama dengan menggunakan sebagai HEADgantinya.

  • git diff [--options] <commit>...<commit> [--] [<path>…]

    Formulir ini untuk melihat perubahan pada cabang yang berisi dan sampai yang kedua <commit>, dimulai pada nenek moyang yang sama dari keduanya <commit>. " git diff A...B" sama dengan " git diff $(git-merge-base A B) B". Anda dapat menghilangkan salah satu dari itu <commit>, yang memiliki efek yang sama dengan menggunakan HEADgantinya.

Untuk berjaga-jaga jika Anda melakukan sesuatu yang eksotis, perlu dicatat bahwa semua <commit>uraian di atas, kecuali dalam dua bentuk terakhir yang menggunakan notasi "..", bisa berupa apa saja <tree>.

Untuk daftar cara mengeja yang lebih lengkap <commit>, lihat bagian "MENGENAL REVISI" di gitrevisions[7]. Namun, "diff" adalah tentang membandingkan dua titik akhir, bukan rentang, dan notasi rentang (" <commit>..<commit>" dan " <commit>...<commit>") tidak berarti rentang seperti yang didefinisikan dalam bagian "TIPE SPESIFIKASI RANG" di gitrevisions[7].

Palec
sumber
Bagi saya $ git diff master...branchdiproduksi fatal: ambiguous argument 'master...branch': unknown revision or path not in the working tree.- apakah ini perintah yang tergantung versi?
Joel Peltonen
Sebenarnya, saya baru menyadari bahwa "cabang" harus menjadi nama cabang Anda, saya pikir itu adalah referensi ke cabang saat ini
Joel Peltonen
4
Anda benar, jawaban saya bergantung pada cabang yang dipanggil branch. Saya memilih untuk tetap dengan nama OP telah dipilih dalam pertanyaan. Jika Anda ingin menggunakan cabang saat ini, ganti branchdengan HEAD.
Palec
14
Perhatikan bahwa Anda dapat menggunakan git diff master...untuk menghindari menentukan cabang (yang saat ini akan diambil).
VasiliNovikov
1
Apakah perintah asli berfungsi setelah Anda check out devel, @ChrisGuest? Mungkin, Git membuat cabang untuk Anda saat checkout, sebagai salinan lokal cabang jarak jauh (biasanya origin/devel). Jika itu masalahnya, git diff origin/devel...bugfix/API-353-api-allows-database-access-whenakan bekerja bahkan sebelum checkout.
Palec
44

Inilah yang bekerja untuk saya:

git diff origin/master...

Ini hanya menunjukkan perubahan antara cabang lokal saya yang dipilih saat ini dan cabang master jarak jauh, dan mengabaikan semua perubahan di cabang lokal saya yang berasal dari gabungan komit.

Jeshurun
sumber
Untuk referensi, jika Anda memerlukan komit komit yang berisi perubahan ini, gunakan git cherry origin/master.
jaytibann
Jika ini menunjukkan banyak sampah yang tidak Anda harapkan, mastermungkin telah me-rebond satu set komitmen keluar dari bawah Anda.
Michael - Di mana Clay Shirky
21

Seperti juga dicatat oleh John Szakmeister dan VasiliNovikov, perintah terpendek untuk mendapatkan perbedaan penuh dari perspektif master di cabang Anda adalah:

git diff master...

Ini menggunakan salinan master lokal Anda.

Untuk membandingkan penggunaan file tertentu:

git diff master... filepath

Contoh keluaran:

Contoh penggunaan

Andrew Schreiber
sumber