Arti Git checkout tanda hubung ganda

274

Apa arti dari tanda hubung ganda sebelum nama file dalam perintah git ini?

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt

Apakah itu wajib? Apakah ini setara dengan

git checkout --ours path/to/file.txt
git checkout --theirs path/to/file.txt
mottalrd
sumber
24
Itu ekspresi shell. Lihat unix.stackexchange.com/questions/11376/…
iltempo
15
@iltempo: Ini sedikit berbeda untuk Git. Untuk Git, itu memisahkan pohon dari jalur, dalam kasus di mana pohon dan jalur mungkin terlihat sama.
Dietrich Epp
@Dietrich_Epp. Saya melihat. Terima kasih telah mengklarifikasi.
iltempo
Juga didokumentasikan dalam stackoverflow.com/a/1192194/6309
VonC
3
Ini adalah duplikat, tetapi duplikat ini setidaknya dapat digunakan oleh kueri 'git double dash'.
durï

Jawaban:

376

Misalkan saya memiliki file bernama path/to/file.txtdi repositori Git saya, dan saya ingin mengembalikan perubahan padanya.

git checkout path/to/file.txt

Sekarang anggaplah file tersebut bernama master...

git checkout master

Aduh! Itu mengubah cabang sebagai gantinya. The --memisahkan pohon Anda ingin memeriksa dari file yang ingin memeriksa.

git checkout -- master

Ini juga membantu kita jika beberapa freako menambahkan file bernama -fke repositori kita:

git checkout -f      # wrong
git checkout -- -f   # right

Ini didokumentasikan di git-checkout: Argument Disambiguation .

Dietrich Epp
sumber
12
Ini berlaku untuk banyak perintah bash, bukan hanya perintah git, ya?
NHDaly
40
@NHDaly: Ya, itu benar. Namun, catatan terminologi: "Bash" hanya memiliki beberapa perintah (mungkin 20 atau lebih), sebagian besar perintah adalah program yang terpisah dari Bash. Ini sebenarnya adalah bagian dari standar POSIX yang --dapat digunakan untuk memisahkan opsi dari argumen lain, sehingga Anda akan melihatnya pada perintah like cpdan mv(yang bukan bagian dari Bash).
Dietrich Epp
6
Adakah ide mengapa sintaks ini tidak dijelaskan dengan benar dalam checkoutdokumentasi perintah?
TanguyP
4
@DietrichEpp Di beberapa tempat, itu terdaftar seperti parameter yang mungkin untuk checkoutperintah, tetapi tidak ada dokumentasi yang menjelaskan apa yang dilakukannya atau mengapa itu digunakan ... yang akhirnya membawa saya ke sini.
chris
7
@ DietrichEpp Benar, tetapi setelah membaca sintaks (dan contoh) sebelum datang ke Stack Overflow, saya masih tidak mengerti mengapa seseorang mau atau tidak mau menggunakan --. Sebagai seseorang yang tidak berasal dari latar belakang linux, tidak jelas apa yang dilakukannya. Bagi saya, itu tampaknya sintaks khusus untuk git, tanpa deskripsi tujuan fungsionalnya. Saya pikir akan lebih baik untuk memiliki deskripsi singkat seperti opsi lain, atau setidaknya tautan ke halaman manual linux .
chris
109

Tanda hubung ganda "-" berarti "akhir dari bendera baris perintah" yaitu, ia memberi tahu perintah sebelumnya untuk tidak mencoba menguraikan apa yang muncul setelah opsi baris perintah.

timmcliu
sumber
2
Untuk kejelasan, di gitdalamnya berarti lebih dari ini, karena itu juga berarti argumen setelah --tidak bisa menjadi nama cabang, dan dengan implikasi argumen sebelumnya --tidak dapat menjadi path file.
Permata Taylor
0

Perhatikan bahwa Anda tidak perlu, karena Git 2.5 (Q2 2015) a ' --' jika argumen Anda menyertakan wildcard ( *)

Heuristik untuk membantu " git <cmd> <revs> <pathspec>" konvensi baris perintah untuk menangkap jalur yang salah ketik adalah memastikan bahwa semua parameter non-rev di bagian selanjutnya dari baris perintah adalah nama file di pohon kerja, tetapi itu berarti " git grep $str -- \*.c" harus selalu disatukan dengan " --", karena tidak ada yang waras akan membuat file yang namanya secara harfiah asterisk-dot-see.

Git 2.5 kehilangan heuristik untuk menyatakan bahwa dengan string wildcard, pengguna mungkin bermaksud memberi kita pathspec .

git checkout 'a*'
# same as
git checkout -- 'a*'

Lihat komit 28fcc0b (02 Mei 2015) oleh Duy Nguyen ( nguyenlocduy) .
(Digabung oleh Junio ​​C Hamano - gitster- dalam komitmen 949d167 , 19 Mei 2015)

pathspec: hindari kebutuhan " --" saat wildcard digunakan

Ketika " --" kurang dari baris perintah dan sebuah perintah dapat mengambil revs dan path, idenya adalah jika sebuah argumen dapat dilihat sebagai perpanjangan SHA-1 dan path, " --" diperlukan atau git menolak untuk melanjutkan.
Saat ini diterapkan sebagai:

  • (1) jika suatu argumen rev, maka itu tidak boleh ada di worktree
  • (2) lain, itu harus ada di worktree
  • (3) lain, " --" diperlukan.

Aturan-aturan ini bekerja untuk jalur literal, tetapi ketika pathspec non-literal terlibat, hampir selalu mengharuskan pengguna untuk menambahkan " --" karena gagal (2) dan (1) benar-benar jarang dipenuhi (ambil " *.c" misalnya, (1) terpenuhi jika ada referensi bernama "*.c ").

Patch ini memodifikasi aturan sedikit dengan mempertimbangkan valid ( *) wildcard pathspec "ada di worktree".
Aturannya menjadi:

  • (1) jika sebuah arg adalah rev, maka ia harus ada di worktree atau tidak menjadi wildcard pathspec yang valid.
  • (2) lain, itu ada di worktree atau merupakan wildcard pathspec
  • (3) lain, " --" diperlukan.

Dengan aturan baru, " --" tidak diperlukan sebagian besar waktu ketika wildcard pathspec terlibat.


Dengan Git 2.26 (Q1 2020), logika disambiguasi untuk membedakan revisi dan pathspec telah di-tweak sehingga karakter-karakter khusus glob yang lolos dari backslash tidak dihitung dalam aturan "wildcard is pathspec".

Lihat komit 39e21c6 (25 Jan 2020) oleh Jeff King ( peff) .
(Digabung oleh Junio ​​C Hamano - gitster- dalam komit 341f8a6 , 12 Feb 2020)

verify_filename(): menangani backslash dalam aturan "wildcard is pathspecs"

Dilaporkan oleh: David Burström
Ditandatangani oleh: Jeff King

Komit 28fcc0b71a ( pathspec: hindari kebutuhan " --" ketika wildcard digunakan, 2015-05-02) diizinkan:

git rev-parse '*.c'

tanpa tanda hubung ganda.

Tapi aturan yang digunakan untuk memeriksa wildcard sebenarnya mencari glob khusus.
Ini terlalu liberal, karena itu berarti suatu pola yang tidak benar-benar melakukan pencocokan wildcard, seperti " a\b", akan dianggap sebagai pathspec.

Jika Anda memiliki file seperti itu di disk, mungkin itu yang Anda inginkan.
Tetapi jika tidak, hasilnya membingungkan: daripada mengatakan "there's no such path a\b ", kami akan menerimanya diam-diam sebagai pathspec yang sangat mungkin tidak cocok dengan apa pun (atau setidaknya bukan apa yang Anda maksudkan).
Demikian juga, mencari jalan " a\*b" tidak memperluas pencarian sama sekali; hanya akan menemukan satu entri, "a*b ".

Komit ini mengalihkan aturan untuk memicu hanya ketika karakter met glob akan memperluas pencarian, yang berarti kedua kasus tersebut sekarang akan melaporkan kesalahan (Anda masih dapat ambigu menggunakan "-- ", tentu saja; kami hanya memperketat heuristik DWIM).

( DWIM: Lakukan Apa yang Saya Maksud )

Perhatikan bahwa kami sama sekali tidak menguji fitur asli di 28fcc0b71a .
Jadi tambalan ini tidak hanya tes untuk kasus sudut ini, tetapi juga menambahkan tes regresi untuk perilaku yang ada.

VONC
sumber