$ git reset -- <file_path>
dapat diatur ulang dengan jalur.
Namun, $ git reset (--hard|--soft) <file_path>
akan melaporkan kesalahan seperti di bawah ini:
Cannot do hard|soft reset with paths.
Jawaban:
Karena tidak ada gunanya (perintah lain sudah menyediakan fungsionalitas itu), dan itu mengurangi potensi untuk melakukan hal yang salah secara tidak sengaja.
Sebuah "hard reset" untuk sebuah jalur baru saja selesai dengan git checkout HEAD -- <path>
(memeriksa versi file yang ada).
Soft reset untuk jalur tidak masuk akal.
Reset campuran untuk jalur adalah apa git reset -- <path>
.
git checkout -- <path>
tidak melakukan hard reset; itu menggantikan isi pohon kerja dengan isi bertahap. git checkout HEAD -- <path>
melakukan hard reset untuk sebuah jalur, mengganti indeks dan pohon kerja dengan versi dari komit HEAD.
reset --hard
dengan jalan akan memberikan potongan yang hilang ini. Git sudah begitu kuat sehingga alasan "Kami tidak membiarkan Anda melakukan ini untuk perlindungan Anda sendiri" tidak berlaku sama sekali: Ada banyak cara untuk melakukan hal yang salah "secara tidak sengaja". Tak satu pun dari yang penting ketika Anda memilikinya git reflog
.
git reset --hard -- <path>
. Ada kasus penggunaan yang sah untuk itu.
Anda dapat mencapai apa yang Anda coba lakukan dengan menggunakan git checkout HEAD <path>
.
Yang mengatakan, pesan kesalahan yang diberikan tidak masuk akal bagi saya (karena git reset
berfungsi dengan baik pada subdirektori), dan saya tidak melihat alasan mengapa git reset --hard
tidak melakukan apa yang Anda minta.
Pertanyaan bagaimana sudah dijawab , saya akan menjelaskan bagian mengapa .
Jadi, apa yang dilakukan git reset ? Bergantung pada parameter yang ditentukan, ia dapat melakukan dua hal berbeda:
Jika Anda menentukan jalur, itu menggantikan file yang cocok di indeks dengan file dari komit (HEAD secara default). Tindakan ini tidak mempengaruhi pohon kerja sama sekali dan biasanya digunakan sebagai kebalikan dari git add.
Jika Anda tidak menentukan jalur, itu akan memindahkan kepala cabang saat ini ke komit yang ditentukan dan, bersama dengan itu , secara opsional menyetel ulang indeks dan pohon kerja ke status komit itu. Ini tambahan perilaku dikendalikan oleh parameter modus:
--soft : tidak menyentuh indeks dan pohon kerja.
--mixed (default): mengatur ulang indeks tetapi bukan pohon kerja.
--hard : setel ulang indeks dan pohon kerja.
Ada juga opsi lain, lihat dokumentasi untuk daftar lengkap dan beberapa kasus penggunaan.
Ketika Anda tidak menentukan komit, defaultnya ke HEAD, jadi git reset --soft
tidak akan melakukan apa-apa, karena ini adalah perintah untuk memindahkan kepala ke HEAD (ke status saat ini). git reset --hard
, di sisi lain, masuk akal karena efek sampingnya , dikatakan pindahkan kepala ke HEAD dan setel ulang indeks dan pohon kerja ke HEAD.
Saya pikir seharusnya sudah jelas sekarang mengapa operasi ini bukan untuk file tertentu berdasarkan sifatnya - ini dimaksudkan untuk memindahkan kepala cabang di tempat pertama, mengatur ulang pohon kerja dan indeks adalah fungsi sekunder.
git checkout
perintah? Dan melakukan penyetelan ulang untuk melakukan hal yang sama akan semakin membingungkan pengguna. Jawaban saya adalah --hard
opsi itu tidak berlaku untuk file tertentu karena ini adalah mode untuk reset cabang, bukan reset indeks. Dan reset pohon yang berfungsi dinamai checkout, seperti yang dapat Anda baca di jawaban lain. Semua itu hanyalah desain antarmuka pengguna Git yang buruk, IMHO.
git checkout
: git reset --
menyetel indeks saja, sementara git checkout --
menyetel pohon kerja saja?
Ada alasan yang sangat penting di balik itu: prinsip checkout
danreset
.
Dalam istilah Git, checkout berarti "membawa ke pohon kerja saat ini". Dan dengan git checkout
kita dapat mengisi pohon kerja dengan data dari area manapun , baik itu dari komit di repositori atau file individual dari komit atau area pementasan (yang bahkan merupakan default).
Sebaliknya, git reset tidak memiliki peran ini. Seperti namanya, ini akan mengatur ulang ref saat ini tetapi selalu memiliki repositori sebagai sumber, terlepas dari "jangkauan" (--soft, --mixed atau --hard).
Rekap:
Oleh karena itu, apa yang bisa sedikit membingungkan adalah keberadaan git reset COMMIT -- files
sejak "menimpa HEAD" hanya dengan beberapa file tidak masuk akal!
Dengan tidak adanya penjelasan resmi, saya hanya dapat berspekulasi bahwa pengembang git menemukan bahwa reset
itu masih merupakan nama terbaik dari sebuah perintah untuk membuang perubahan yang dibuat pada area pementasan dan, mengingat satu-satunya sumber data adalah repositori, maka " mari kita perpanjang fungsionalitas "daripada membuat perintah baru.
Jadi entah bagaimana git reset -- <files>
sudah agak luar biasa: itu tidak akan menimpa HEAD. IMHO semua variasi seperti itu akan menjadi pengecualian. Bahkan jika kita dapat membayangkan sebuah --hard
versi, versi lain (misalnya --soft
) tidak akan masuk akal.
git reset -- <files>
merasa seperti ditambahkan karena ini adalah fitur yang berguna tetapi tidak ada yang yakin di mana perintah itu harus diletakkan. Untungnya sekarang kami memiliki lebih banyak fitur waras git restore
yang memiliki fungsionalitas git checkout -- <path>
git checkout <commit> -- <path>
dan git reset [<commit>] -- <path>
dengan default yang jauh lebih waras dan bahkan lebih banyak fitur yang tidak dapat Anda lakukan sebelumnya (Bertentangan dengan apa yang dikatakan jawaban yang diterima. Sekarang Anda akhirnya dapat dengan mudah memulihkan hanya pohon yang berfungsi, tanpa menyentuh indeks).
Pastikan Anda memberi garis miring antara origin atau upstream (source) dan cabang sebenarnya:
git reset --hard origin/branch
atau
git reset --hard upstream/branch`
The git reset
pengguna daftar 3 cara doa:
2 adalah file-bijaksana: Ini tidak mempengaruhi pohon kerja , tetapi hanya beroperasi pada file dalam indeks yang ditentukan oleh <paths>
:
git reset [-q] [<tree-ish>] [--] <paths>..
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
1 adalah komitmen-bijaksana: Beroperasi pada semua file yang direferensikan <commit>
, dan dapat mempengaruhi pohon kerja:
git reset [<mode>] [<commit>]
Tidak ada mode pemanggilan yang hanya beroperasi pada file tertentu dan memengaruhi pohon kerja.
Jika Anda ingin keduanya:
Anda dapat menggunakan alias ini di file konfigurasi git Anda:
[alias]
reco = !"cd \"${GIT_PREFIX:-.}\" && git reset \"$@\" && git checkout \"$@\" && git status --short #" # Avoid: "fatal: Cannot do hard reset with paths."
Anda kemudian dapat melakukan salah satu dari:
$ git reco <paths>
$ git reco <branch/commit> <paths>
$ git reco -- <paths>
(Mnenonic untuk reco
: re
set && c
heck o
ut)
git checkout -- <path>
harus diganti dengangit reset --hard <path>
. Ini jauh lebih masuk akal ...