Apa perbedaan antara titik ganda “..” dan tiga titik “…” dalam rentang komit Git?

190

Apa perbedaan antara perintah berikut ?:

git diff foo master   # a 
git diff foo..master  # b
git diff foo...master # c

Manual diff membicarakannya:

Membandingkan cabang

$ git diff topic master    <1>
$ git diff topic..master   <2>
$ git diff topic...master  <3>
  1. Perubahan antara ujung topik dan cabang master.
  2. Sama seperti di atas.
  3. Perubahan yang terjadi pada cabang master sejak saat cabang topik dimulai.

tetapi tidak sepenuhnya jelas bagi saya.

chrisjlee
sumber
Meskipun pertanyaannya bukan duplikat, jawaban ini menunjukkan secara grafis arti dari ..dan ...dalam git diffdan artinya yang berbeda git log.
Mark Longair

Jawaban:

335

Karena saya sudah membuat gambar-gambar ini, saya pikir mungkin ada gunanya menggunakannya dalam jawaban lain, meskipun deskripsi perbedaan antara ..(titik-titik) dan ...(titik-titik-titik) pada dasarnya sama dengan jawaban manojlds .

Perintah git diffbiasanya¹ hanya menunjukkan kepada Anda perbedaan antara status pohon antara tepat dua titik dalam grafik komit. The ..dan ...notasi di git diffmemiliki arti sebagai berikut:

Sebuah ilustrasi tentang berbagai cara menentukan commit untuk git diff

Dengan kata lain, git diff foo..barpersis sama dengan git diff foo bar; keduanya akan menunjukkan kepada Anda perbedaan antara ujung kedua cabang foodan bar. Di sisi lain, git diff foo...barakan menunjukkan kepada Anda perbedaan antara "basis gabungan" dari dua cabang dan ujung bar. "Basis penggabungan" biasanya merupakan komit terakhir yang sama di antara kedua cabang tersebut, jadi perintah ini akan menunjukkan kepada Anda perubahan yang bartelah diperkenalkan pada pekerjaan Anda , sementara mengabaikan semua yang telah dilakukan pada foowaktu yang bersamaan.

Itu semua yang perlu Anda ketahui tentang ..dan ...notasi di git diff. Namun...


... sumber kebingungan yang umum di sini adalah hal itu ..dan ...berarti hal-hal yang agak berbeda ketika digunakan dalam perintah seperti git logyang mengharapkan serangkaian commit sebagai satu atau lebih argumen. (Semua perintah ini pada akhirnya digunakan git rev-listuntuk mengurai daftar commit dari argumen mereka.)

Arti dari ..dan ...untuk git logdapat ditampilkan secara grafis seperti di bawah ini:

Sebuah ilustrasi tentang berbagai cara menentukan rentang komit untuk log git

Jadi, git rev-list foo..barmenunjukkan kepada Anda segala sesuatu di cabang baryang tidak juga di cabang foo. Di sisi lain, git rev-list foo...barmenunjukkan semua komitmen yang ada di salah satu foo atau bar , tetapi tidak keduanya . Diagram ketiga hanya menunjukkan bahwa jika Anda membuat daftar dua cabang, Anda mendapatkan komit yang ada di salah satu atau keduanya.

Yah, bagaimanapun juga saya merasa sedikit membingungkan, dan saya pikir diagram graph commit membantu :)

¹ Saya hanya mengatakan "biasanya" karena ketika menyelesaikan konflik gabungan, misalnya, git diffakan menunjukkan kepada Anda gabungan tiga arah.

Mark Longair
sumber
1
Saya suka diagram Anda. Saya datang dengan saya sendiri beberapa waktu lalu juga . Saya punya beberapa ide untuk git diffdiagram saya sendiri yang akan saya buat nanti.
34
Apakah seseorang memperhatikan? Efek dari ..dan ...nuansa terbalik di git diff(dibandingkan dengan git rev-list)!
Robert Siemer
2
Anda memiliki saya di "Itu saja yang perlu Anda ketahui [...]. Namun ...". :-) Git penuh dengan hal-hal seperti ini di mana notasi dan terminologi yang sama memiliki arti yang berbeda dalam konteks yang berbeda; terima kasih telah menjelaskan ini dengan baik.
ShreevatsaR
Terima kasih telah menyebutkan daftar rev. Saya menemukan pertanyaan ini sambil mencari cara melakukan apa yang dilakukan rev-list melalui rev-parse.
Fisikawan Gila
"Dengan kata lain, git diff foo..barpersis sama dengan git diff foo bar; keduanya akan menunjukkan kepadamu perbedaan antara ujung dua cabang foo dan bar." Apa sebenarnya yang Anda maksud dengan "perbedaan antara ujung kedua cabang"?
Asad Moosvi
60

Versi gabungan saya dari .. vs ... dengan diff vs log

Diff vs Log & .. vs ..

DolphinDream
sumber
3
ini akan sangat baik, jika saja tidak memiliki begitu banyak warna berbeda dan mengatur operasi dicampur bersama dengan ../ ...barang. Sebagai contoh di log A...Bdalamnya tidak jelas apakah perintah mengembalikan persimpangan (bagian putih diagram) atau sisa dari persatuan AB (hijau). Ini akan lebih ke titik tanpa operan dan hanya 1 warna.
xealits
1
Jika hal ini benar-benar menjadi diff A..B<-> log A...B, yaitu, tidak benar-benar diff dengan 2 titik, sesuai dengan log dengan 3 titik (!)? Atau apakah ada kesalahan ketik pada gambar. Melihat bagaimana titik-titik diberi kode warna, menurut saya ada kesalahan ketik pada gambar. Pojok kiri bawah: log A...Bseharusnya log A..B, kanan (?). Dan login hanya ke kanan seharusnya ...tidak ...
KajMagnus
1
Hai DolphinDream, terima kasih untuk sosok Anda. Saya menggunakannya sebagai referensi di sini: gitlab.com/tortoisegit/tortoisegit/issues/3427#note_227200695
Yue Lin Ho
1
@KajMagnus sebenarnya warna merah / biru hanya digunakan untuk membedakan antara 2-titik dan 3-titik (terlepas dari digunakan dengan diff atau log). Diagramnya benar. Di kolom pertama, hasil dari diff dengan 2-dots mirip dengan log dengan 3-dots (maka diagram tujuan keseluruhan dimulai dengan). Perbedaan dengan 2-titik memberikan perubahan kode pada kedua putaran ke titik divergensi (diilustrasikan oleh gelembung hijau di sekitar komit dan bagian hijau dari diagram van) sementara log dengan 3-titik memberikan perubahan log (melakukan pesan) di kedua putaran turun ke titik divergensi.
DolphinDream
28

git diff foo master Beda komit atas dan kepala dari foo dan master.

git diff foo..master Cara lain melakukan hal yang sama.

git diff foo...masterBerbeda dari leluhur ( git merge-base foo master) foo dan master pada ujung master. Dengan kata lain, hanya menunjukkan perubahan yang diperkenalkan cabang master sejak nenek moyang yang sama dengan foo.

Contoh dari GitHub ini menjelaskan kapan harus menggunakan keduanya:

Misalnya, jika Anda membuat cabang 'dev' dan menambahkan fungsi ke file, maka kembali ke cabang 'master' Anda dan hapus baris dari README, dan kemudian jalankan sesuatu seperti ini:

$ git diff master dev

Ini akan memberi tahu Anda bahwa suatu fungsi telah ditambahkan dari file pertama dan sebuah baris telah ditambahkan ke README. Mengapa? Karena di cabang, README masih memiliki garis asli, tetapi pada 'master' Anda telah menghapusnya - jadi langsung membandingkan snapshots sepertinya 'dev' menambahkannya.

Apa yang benar-benar ingin Anda bandingkan adalah apa yang telah 'diubah' sejak cabang Anda berbeda. Untuk melakukan itu, Git memiliki tulisan singkat yang bagus:

$ git diff master...dev
manojlds
sumber
2
git diff foo ... perubahan master yang telah diperkenalkan cabang master karena itu adalah leluhur bersama dengan foo
0fnt
@ manojlds ok, pertanyaan yang sangat berbeda, jika Anda berada di cabang dev dan melakukan perubahan Anda (fungsi) dan mendorong perubahan ke cabang dev jauh apakah ini berarti perubahan yang terlihat hanya fungsi atau fungsi dan readme?
David
Jika saya tidak salah, permintaan tarik GitHub menggunakan triple dot. Apakah itu benar?
Shaun Luttin
Tautan rusak ke halaman contoh GitHub.
K.-Michael Aye
6
git diff foo master

akan menunjukkan perbedaan antara topik dan cabang utama pada saat itu

git diff foo..master

ini juga akan menunjukkan perbedaan antara topik dan cabang utama pada titik waktu tersebut

git diff foo...master

ini akan menunjukkan semua perbedaan antara saat topik dibuat dari cabang dan setelah

jadi 2 perintah pertama adalah sama dan yang terakhir hanya menunjukkan tampilan yang lebih luas dalam sejarah diff

italiano40
sumber
1

pohon log git

Gambar atas setara dengan pohon grafik bawah

A0 <- A1 <- A2 <- A3 (master)
   \
    C0 <- C1 (test)

Sebuah gambar bernilai ribuan kata, perbedaannya .. ... ^ditunjukkan di bawah ini.

$ git log master..test
# output C0 C1

$ git log ^master test
# output C0 C1

$ git log master…test
# output A1 A2 A3 C0 C1
yanhaijing
sumber