Neden git yoldan sert / yumuşak sıfırlama yapamıyor?


138

$ git reset -- <file_path> yolu ile sıfırlayabilirsiniz.

Ancak, $ git reset (--hard|--soft) <file_path>aşağıdaki gibi bir hata bildirir:

Cannot do hard|soft reset with paths.

Yanıtlar:


143

Çü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.


72
Şahsen ben düşünüyorum git checkout -- <path>edilmelidir yerini ile git reset --hard <path>. Çok daha mantıklı ...
vergenzt

24
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.
Dan Fabulich

1
@EdPlunkett Er, cevabın ikinci cümlesi size hangi komutun işlevselliği sağladığını söyler.
Amber

16
-1: Söz konusu revizyonun silinmesi, söz konusu revizyon silinmiş dosyalar içeriyorsa, çalışma kopyasından dosyaları kaldırmaz. reset --hardbir 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.
void.pointer

1
@ void.pointer checkout tarafından belirtildiği gibi dosyalar kaldırılmaz. Bu davranışı istiyorsanız, bu cevaba bakın. Yine de, umarım bir gün alacağız git reset --hard -- <path>. Bunun meşru kullanım örnekleri vardır.
Mariusz Pawelski

18

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 resetalt dizinlerde gayet iyi çalışıyor gibi ) ve neden git reset --hardistediğini tam olarak yapmamanın bir neden göremiyorum .


kullanarak ödeme reset --soft aynı değildir değişiklikleri, aşamalarında
WORC

11

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 --softkafayı 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.


sıfırlamanın ilk başta bir şube başlığını hareket ettirmesi amaçlanmıştır, ancak çalışma ağacını ve tüm taahhütler için dizini sıfırlama ek işlevine ve belirli dosyalar için dizini sıfırlama işlevine sahip olduğu için neden olmasın dosyalar için çalışma ağacını sıfırlama işlevselliğine sahip misiniz? OP'nin sorduğu şey bu.
Danilo Souza Morães

Belki de bu işlevsellik (belirli dosyalar için çalışma ağacının sıfırlanması) git checkoutkomut 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, --hardseç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ı.
kullanıcı

İlk seçenek aşağıdakilerle karşılaştırılıyor git checkout: git reset --yalnızca dizini ayarlarken, yalnızca git checkout --çalışma ağacını ayarlar?
seeker_of_bacon

4

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`

Lütfen soruyu tekrar okuyun.
Xerus

3

: Arkasında çok önemli bir nedeni var ilkeleri checkoutvereset .

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:

  • çıkış : Her yerden (dizin / repo taahhüdü) -> çalışma ağacı
  • reset : Repo commit -> HEAD üzerine yaz (ve isteğe bağlı olarak dizin ve çalışma ağacı)

Bu nedenle, biraz kafa karıştırıcı olabilecek şey, git reset COMMIT -- filessadece 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 resetatı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 --hardsürümü tasarlayabilsek bile , diğerleri (örneğin --soft) mantıklı olmazdı.


Bu yanıtı beğendim. Gerçekten, 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 restoreiş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).
Mariusz Pawelski

0

açıklama

git resetManuel 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.

Geçici çözüm

Her ikisini de yapmak istiyorsanız:

  • Dosyaların dizin / önbellek sürümünü sıfırlama
  • Dosya (lar) ı kullanıma alma (yani, çalışma ağacının dizin ve tamamlama sürümüyle eşleşmesini sağlama)

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: reset && check out)


-2

git reset --soft HEAD ~ 1 dosya adı taahhüdü geri alır ancak değişiklikler yerel olarak kalır. dosya adı olabilir - kaydedilen tüm dosyalar için


6
ölümcülCannot do soft reset with paths.
alt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.