Yanıtlar:
Çünkü bir anlamı yok (diğer komutlar bu işlevselliği zaten sağlıyor) ve yanlışlıkla yanlış şeyi yapma olasılığını azaltır.
Bir yol için "donanımdan sıfırlama" işlemi yalnızca git checkout HEAD -- <path>
(dosyanın mevcut sürümüne bakılarak) yapılır.
Bir yol için yumuşak bir sıfırlama anlamlı değildir.
Bir yol için karışık bir sıfırlama ne git reset -- <path>
yapar.
git checkout -- <path>
donanımdan sıfırlama yapmaz; çalışma ağacı içeriklerini aşamalı içeriklerle değiştirir. git checkout HEAD -- <path>
hem dizin hem de çalışma ağacını HEAD komutunun sürümüyle değiştirerek yol için donanımdan sıfırlama yapar.
reset --hard
bir yol bu eksik parçayı sağlayacaktır. Git zaten o kadar güçlü ki, "Bunu kendi güvenliğiniz için yapmanıza izin vermiyoruz" mazereti sıfır su tutar: Yanlışlıkla "yanlışlıkla" yapmanın birçok yolu vardır. Bunların hiçbiri sahip olduğunuzda hiçbir şekilde önemli değil git reflog
.
git reset --hard -- <path>
. Bunun meşru kullanım örnekleri vardır.
Yapmaya çalıştığınız şeyi başarabilirsiniz git checkout HEAD <path>
.
Bununla birlikte, sağlanan hata mesajı benim için bir anlam ifade etmiyor ( git reset
alt dizinlerde gayet iyi çalışıyor gibi ) ve neden git reset --hard
istediğini tam olarak yapmamanın bir neden göremiyorum .
Zaten nasıl cevaplandığı sorusu , neden kısmını açıklayacağım .
Peki, git reset ne yapar ? Belirtilen parametrelere bağlı olarak, iki farklı şey yapabilir:
Bir yol belirtirseniz, dizindeki eşleşen dosyaları yerine kaydedilen dosyalarla (varsayılan olarak HEAD) değiştirir. Bu eylem, çalışma ağacını hiç etkilemez ve genellikle git add öğesinin tersi olarak kullanılır.
Bir yol belirtmezseniz, geçerli şube başlığını belirtilen bir işleme taşır ve bununla birlikte isteğe bağlı olarak dizini ve çalışma ağacını bu taahhüdün durumuna sıfırlar. Bu ek davranış mode parametresi tarafından denetlenir:
--soft : dizine ve çalışma ağacına dokunmayın.
--mixed (varsayılan): dizini sıfırlar ancak çalışma ağacını sıfırlamaz.
--hard : dizini ve çalışma ağacını sıfırlar.
Başka seçenekler de vardır, tam liste ve bazı kullanım durumları için belgelere bakın.
Bir kesinleştirme belirtmediğinizde, varsayılan olarak HEAD (varsayılan) HEAD (BAŞLAT) seçeneğidir, bu nedenle git reset --soft
kafayı HEAD (geçerli durumuna) taşımak için bir komut olduğu için hiçbir şey yapmaz. git reset --hard
Öte yandan, yan etkileri nedeniyle mantıklıdır , kafayı HEAD'e taşıyın ve endeksi ve çalışma ağacını HEAD'a sıfırlayın.
Bence bu işlemin doğası gereği neden belirli dosyalar için olmadığı açık olmalı - bir dal başını ilk etapta hareket ettirmek, çalışma ağacını sıfırlamak ve dizin ikincil işlevselliktir.
git checkout
komut olarak zaten mevcut olduğundan ? Aynı şeyi yapmak için sıfırlama yapmak kullanıcıları daha fazla karıştırır. Cevabım, --hard
seçeneğin belirli dosyalar için geçerli olmamasıydı, çünkü dizin sıfırlama için bir mod, şube sıfırlama için bir mod. Ve diğer ağaçlarda okuyabileceğiniz gibi, çalışma ağacını sıfırlama, kasa olarak adlandırılır. Tüm bunlar Git'in kullanıcı arayüzü IMHO'nun kötü bir tasarımı.
git checkout
: git reset --
yalnızca dizini ayarlarken, yalnızca git checkout --
çalışma ağacını ayarlar?
Başlangıç noktası veya yukarı akış (kaynak) ile gerçek dal arasına eğik çizgi koyduğunuzdan emin olun:
git reset --hard origin/branch
veya
git reset --hard upstream/branch`
: Arkasında çok önemli bir nedeni var ilkeleri checkout
vereset
.
Git terimleriyle, ödeme "geçerli çalışma ağacına getir" anlamına gelir. Ve git checkout
çalışma ağacını herhangi bir alandan gelen verilerle doldurabiliriz, bu, veri havuzundaki bir taahhütten veya bir taahhütten veya hazırlama alanından (varsayılan bile olsa) bireysel dosyalardan olabilir .
Buna karşılık, git sıfırlama bu rolü yoktur. Adından da anlaşılacağı gibi, mevcut ref sıfırlar ama her zaman sahip depoyu bağımsız "ulaşılabilecek" nin, bir kaynak olarak (--soft, --mixed veya --hard).
Recap:
Bu nedenle, biraz kafa karıştırıcı olabilecek şey, git reset COMMIT -- files
sadece bazı dosyalarla "HEAD üzerine yazma" nın varlığı mantıklı değildir!
Resmi bir açıklama olmadığı durumlarda, sadece git geliştiriciler bulundu spekülasyon olabilir reset
atılması için bir komut en iyi isim deposu yalnızca veri kaynağı oldu verilmiş, evreleme alana yapılan ve değişiklikleri hala, o zaman " en uzatmak let işlevselliği "yerine yeni bir komut oluşturma.
Yani bir şekilde git reset -- <files>
biraz istisnai: HEAD'in üzerine yazmıyor. IMHO tüm bu varyasyonlar istisna olacaktır. Bir --hard
sürümü tasarlayabilsek bile , diğerleri (örneğin --soft
) mantıklı olmazdı.
git reset -- <files>
eklenmiş gibi düştü, çünkü bu kullanışlı bir özelliktir, ancak hiç kimse hangi komutu kullanması gerektiğinden emin değildi. Neyse ki şimdi git restore
işlevselliği olan git checkout -- <path>
git checkout <commit> -- <path>
ve git reset [<commit>] -- <path>
çok daha akılda kalıcı varsayılanlara ve daha önce yapamayacağınız daha fazla özelliğe sahip çok daha aklı başındayız (Kabul edilen cevabın söylediklerinin aksine. Sonunda sadece çalışma ağacını dizine dokunmadan kolayca geri yükleyebilirsiniz).
git reset
Manuel listeleri çağırma 3 yolu:
2 dosya yönündedir: Bunlar çalışma ağacını etkilemez, sadece dizin tarafından belirtilen dizinde çalışır <paths>
:
git reset [-q] [<tree-ish>] [--] <paths>..
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
1 is-bilge taahhüt: ile çalışır tüm dosyaları başvurulan içinde <commit>
ve olabilecek çalışma ağacını etkiler:
git reset [<mode>] [<commit>]
Sadece belirtilen dosyaları üzerinde çalışan çağırma hiçbir mod var ve çalışma ağacını etkiler.
Her ikisini de yapmak istiyorsanız:
Bu diğer adı git config dosyanızda kullanabilirsiniz:
[alias]
reco = !"cd \"${GIT_PREFIX:-.}\" && git reset \"$@\" && git checkout \"$@\" && git status --short #" # Avoid: "fatal: Cannot do hard reset with paths."
Daha sonra aşağıdakilerden birini yapabilirsiniz:
$ git reco <paths>
$ git reco <branch/commit> <paths>
$ git reco -- <paths>
(Mnenonic for reco
: re
set && c
heck o
ut)
git checkout -- <path>
edilmelidir yerini ilegit reset --hard <path>
. Çok daha mantıklı ...