Soru İşlemden önce 'git' nasıl geri alınır?


Komutu kullanarak yanlışlıkla dosya ekledim:

git add myfile.txt

Henüz kaçmadım git commit. Bunu geri almanın bir yolu var mı? Bu dosyalar bu sürece dahil edilmeyecek mi?


Şimdiye kadar 48 cevap var (bazıları silindi). Yeni bilgileriniz olmadığı sürece lütfen yeni bir tane eklemeyin.


7464
2017-12-07 21:57


Menşei


Git v1.8.4'ten başlayarak, aşağıdaki tüm cevaplar aşağıdaki gibidir: HEAD veya head şimdi kullanabilir @ yerine HEAD yerine. Görmek bu cevap (son bölüm) Bunu neden yapabileceğinizi öğrenmek için.
Bir dosyayı yazmanın tüm yollarını gösteren küçük bir yazlık yaptım: stackoverflow.com/questions/6919121/... - Daniel Alder
Neden git ödeme yapmıyorsunuz? - Erik Reppen
@ErikReppen git checkout taahhüt dizinindeki aşamalı değişiklikleri kaldırmaz. Bu, yalnızca son değişiklik yapılan revizyona yapılan aşamasız değişiklikleri geri döndürüyor - ki bu da benim istediğim gibi değil, bu değişiklikleri istiyorum, sadece onları daha sonraki bir taahhütte istiyorum. - paxos1977
Eclipse kullanırsanız, bu işlemin bağlı iletişim kutusundaki dosyaların işaretini kaldırmak kadar basittir. - Hamzahfrq


Cevaplar:


Geri alabilirsiniz git add ile işlem yapmadan önce

git reset <file>

Başka bir şey değiştirmeden mevcut dizin ("işlenecek hakkında" liste) kaldıracak.

Kullanabilirsiniz

git reset

Tüm değişikliklerin düzeltilmesi için herhangi bir dosya adı olmadan. Bu, makul bir sürede tek tek listelenecek çok fazla dosya olduğunda kullanışlı olabilir.

Git'in eski sürümlerinde, yukarıdaki komutlar eşdeğerdir. git reset HEAD <file> ve git reset HEAD sırasıyla, ve başarısız olur HEAD undefined (henüz repo'unuzda herhangi bir taahhütte bulunmadınız) veya belirsiz (çünkü bir şube yarattınız) HEADYapmaması gereken aptal bir şeydir. Bu Git 1.8.2'de değiştirildiBununla birlikte, Git'in modern sürümlerinde, yukarıdaki ilk komutları yapmadan önce yukarıdaki komutları kullanabilirsiniz:

"git reset" (seçenekler veya parametreler olmadan) ne zaman hata yapmak için kullanılır      Tarihinizde hiçbir taahhütünüz yok, ama şimdi size veriyor      boş bir endeks (mevcut olmayan vaatle eşleştirmek için bile değilsiniz).


8379
2017-12-07 22:30



Tabii ki, bu gerçek bir geri alma değil, çünkü yanlış git add önceki aşamalı bir sürümün üzerine yazmış, onu kurtaramıyoruz. Aşağıdaki cevabımda bunu açıklığa kavuşturmaya çalıştım. - leonbloy
git reset HEAD *.ext nerede ext unadd yapmak istediğiniz uzantının dosyalarıdır. Benim için *.bmp & *.zip - boulder_ruby
@Jonny, indeksi (aka evreleme alanı) içerir herşey dosyalar, sadece değiştirilen dosyalar değil. HEAD tarafından işaret edilen taahhütteki tüm dosyaların bir kopyası olarak "bir yaşamı başlatır" (bir işlemi veya bir repoyu klonladığınızda). Eğer öyleyse Kaldır dizinden bir dosya (git rm --cached) bir taahhütte bulunmaya hazırlandığınız anlamına gelir siler bu dosya. git reset HEAD <filename> Öte yandan dosyayı HEAD'den dizine kopyalayacak, böylece bir sonraki işlem bu dosyada herhangi bir değişiklik yapılmayacak. - Wildcard
Sadece bir tane olduğunu keşfettim. git reset -p aynen git add -p. Bu harika! - donquixote
Aslında sen Önceden sahnelenen ancak istenmeyen değişiklikler üzerine yazabilir ama kullanıcı dostu olmayan bir şekilde ve% 100 güvenli değil (en azından benim bulduğum): goto .git / object, zamanda oluşturulmuş dosyaları ara git add kurtarmak istersiniz (61/3AF3... -> nesne kimliği 613AF3...), sonra git cat-file -p <object-id> (Birkaç saatlik çalışmayı telafi etmeye değer olabilir ama aynı zamanda daha sık işlemek için bir ders ...) - Peter Schneider


İstediğiniz:

git rm --cached <added_file_to_undo>

Akıl Yürütme:

Ben yeniyken, ilk denedim

git reset .

(tüm ilk eklememi geri almak için), sadece bu (değil) yardımcı mesaj almak için:

fatal: Failed to resolve 'HEAD' as a valid ref.

Bunun sebebi, HEAD ref'in (şube?) İlk işlemden sonraya kadar mevcut olmamasıdır. Yani, benimki gibi, iş akışınız şu gibi bir şey olsaydı, benimle aynı yeni başlayanların problemine girersiniz:

  1. Git, yeni sıcaklığı denemek için harika yeni proje dizinine cd
  2. git init
  3. git add .
  4. git status

    ... bir sürü bok kayar ...

    => Kahretsin, hepsini eklemek istemedim.

  5. google "undo git ekle"

    => yığın taşması bulmak - yay

  6. git reset .

    => fatal: 'HEAD' öğesini geçerli bir ref olarak çözemedi.

Dahası, orada bir hata kaydedildi posta listesinde bunun yararsızlığına karşı.

Ve doğru çözüm, Git durum çıktısında doğruydu (ki, evet, 'saçma' olarak glossed)

...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...

Ve çözüm gerçekten kullanmaktır git rm --cached FILE.

Burada başka bir yerde uyarıları not edin - git rm Dosyanın yerel çalışma kopyasını siler, ancak değil Eğer kullanırsan --cached. İşte sonucu git help rm:

--cached       Yolları yalnızca dizinden kaldırmak ve kaldırmak için bu seçeneği kullanın.       Değiştirilmiş olsun ya da olmasın, çalışan ağaç dosyaları bırakılacaktır.

Kullanmaya devam ediyorum

git rm --cached .

her şeyi kaldırmak ve tekrar başlamak için. Yine de işe yaramadı çünkü add . özyinelemeli rm ihtiyaçlar -r tekrarlamak. İç çekmek.

git rm -r --cached .

Tamam, şimdi başladığım yere döndüm. Bir dahaki sefere kullanacağım -n Kuru bir çalışma yapmak ve neyin ekleneceğini görmek için:

git add -n .

Güvenmeden önce her şeyi güvenli bir yere sıkıştırdım git help rm hakkında --cached hiçbir şeyi yok etmeyin (ve eğer onu yanlış yazsaydım).


1954
2018-03-25 16:20



Hah. Aynı süreci takip ettim. Hariç ben vazgeçtim ve dedi rm -rf .git, git init çünkü güvenmedim git rm --cached çalışmamı saklamak için. Git bazı yerlerde hala aşırı karmaşık olduğu için biraz diyor. git unstage sadece stok standart bir komut olmalı, takma ad olarak ekleyebilir miyim umrumda değil. - Adrian Macneil
Benim için git diyor ki git reset HEAD <File>... - drahnr
Git <a1> <a1> </ a1> <file> aslında doğru <a0> </ a0>, <file> deposunun içine ilk ithalatı ise doğru yanıttır. Dosyaya bir değişiklik yapılmaya çalışılıyorsa, git sıfırlama doğru cevaptır. Bu cevabın yanlış olduğunu söyleyen insanlar farklı bir soru üzerinde düşünüyorlar. - Barry Kelly
Bu aslında çalışacak, ama bir tek Dosyanın daha önce olmadığı yerde, ya da git add komut yeni dosyalar ekledi, Ama değil varolan dosyalarda değişiklikler. - naught101
sadece ne kadar anlamsız ve kıvrık git olduğunu göstermeye gider. Paralel "geri al" komutları yerine, bunları nasıl geri alacağınızı öğrenmelisiniz. Bacağını çabuk kumda serbest bırakmaya çalışıp, sonra kolunu sıkıştırarak, diğer kolunu sıkıştırarak ... her komut, seçenekler için açılan menülerle GUI aracılığıyla yapılmalı ... Tüm kullanıcı arayüzünü düşün, Elde ettiğimiz verimlilik kazançları, ancak bu bir retro komut satırı arayüzüne sahip olduğumuz karışıklık var. Git GUI programları bunu daha sezgisel hale getirmiyor. - ahnbizcad


Eğer yazarsanız:

git status

git, nasıl ayarlanacağına dair talimatlar da dahil olmak üzere, neyin sahneleneceğini size söyleyecektir:

use "git reset HEAD <file>..." to unstage

Git'in bu gibi durumlarda doğru şeyi yapmam için iyi bir iş çıkardığını buldum.

Not: Son git sürümleri (1.8.4.x) bu mesajı değiştirdi:

(use "git rm --cached <file>..." to unstage)

484
2017-12-07 23:22



Mesajın, added dosyası zaten izleniyordu ( add sadece önbellek için yeni bir sürüm kaydedildi - burada mesajınızı gösterecektir. Başka bir yerde, dosya daha önce sahnelenmemişse, görüntülenecektir use "git rm --cached <file>..." to unstage - leonbloy
Harika! git reset HEAD <file> Bir dosya silme işlemini kaldırmak istediğinizde çalışacak tek kişi - skerit
Git sürüm 2.14.3 diyor git reset HEAD unutma. - seaturtle


Netleşmeştirmek: git add Geçerli çalışma dizinindeki değişiklikleri evreleme alanı (Indeks).

Bu süreç denir sahneleme. Yani en doğal komuta evre değişiklikler (değiştirilen dosyalar) açık olanıdır:

git stage

git add sadece takma ad yazmak için daha kolay git stage

Yazık ki yok git unstage ne de git unadd emreder. İlgili olanı tahmin etmek veya hatırlamak daha zordur. ama oldukça açık:

git reset HEAD --

Bunun için kolayca bir takma ad oluşturabiliriz:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

Son olarak, yeni komutlarımız var:

git add file1
git stage file2
git unadd file2
git unstage file1

Şahsen daha kısa takma adlar kullanıyorum:

git a #for staging
git u #for unstaging

220
2017-09-10 20:28



"Hamle"? Bu, çalışma dizininden gittiğini gösterir. Konu bu değil. - Thomas Weller
Neden belli oluyor? - Lenar Hoyt


Kabul edilen cevaba ek olarak, yanlışlıkla eklediğiniz dosya çok büyükse, büyük olasılıkla dizinden çıkardıktan sonra bile bunu farkedeceksiniz.git reset', hala alan işgal gibi görünüyor .git dizin. Bu endişelenecek bir şey değil, dosya gerçekten de depoda, ancak sadece "gevşek bir nesne" olarak, diğer depolara (klonlama, itme yoluyla) kopyalanmayacak ve alan sonunda geri kazanılacak - yine de belki çok yakında değil. Eğer endişeli iseniz, şunları çalıştırabilirsiniz:

git gc --prune=now

Güncelleştirme (en fazla oyu alan cevaplardan kaynaklanabilecek bazı karışıklıkları giderme girişimi aşağıdadır):

Yani, gerçek olan geri alma arasında git add?

git reset HEAD <file> ?

veya

git rm --cached <file>?

Kesinlikle konuşuyorum ve yanılmıyorsam: Yok.

git add  Geri alınamayan - Genel olarak güvenle.

Önce ne hatırlayalım git add <file> aslında yapar:

  1. Eğer <file> oldu daha önce izlenmemiş, git add  önbelleğe eklermevcut içeriğiyle.

  2. Eğer <file> oldu zaten izlendi, git add  mevcut içeriği kaydeder (anlık görüntü, sürüm) önbellek. GIT'de bu işlem hala deniyor eklemek, (sadece güncelleştirme it), çünkü bir dosyanın iki farklı versiyonu (enstantane) iki farklı öğe olarak kabul edilir: bu nedenle, aslında daha sonra işlenmek üzere önbelleğe yeni bir öğe ekliyoruz.

Bunun ışığında, soru biraz belirsizdir:

Komutu kullanarak yanlışlıkla dosya ekledim ...

OP'nin senaryosu ilk defa (izlenimsiz dosya) gibi görünüyor, izlenen öğelerden dosyayı (sadece geçerli içerikleri değil) kaldırmak için "geri al" seçeneğini istiyoruz. Eğer Bu durumda, o zaman çalıştırmak için tamam git rm --cached <file>.

Ve biz de koşabiliriz git reset HEAD <file>. Bu genel olarak tercih edilir, çünkü her iki senaryoda da çalışır: zaten izlenen bir öğenin bir sürümünü yanlış eklediğimizde geri almayı da yapar.

Ama iki uyarı var.

Birincisi: (cevapta belirtildiği gibi) sadece bir senaryo vardır. git reset HEAD çalışmıyor, ama git rm --cached yapar: yeni bir depo (hiçbir taahhüt). Ama, gerçekten, bu pratik olarak alakasız bir durum.

İkincisi: Farkında ol git reset HEAD  Önceden önbelleğe alınmış dosya içeriğini sihirli olarak kurtaramaz, sadece HEAD'den yeniden eşler. Yanlış yönlendirilmişse git add önceki aşamalı bir yayından kaldırılmış sürümün üzerine yazdı, onu kurtaramıyoruz. Bu yüzden, kesinlikle konuşuyoruz, geri alamıyoruz.

Örnek:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # first add  of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt   
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # oops we didn't mean this
$ git reset HEAD file.txt  # undo ?
$ git diff --cached file.txt  # no dif, of course. stage == HEAD
$ git diff file.txt   # we have lost irrevocably "version 2"
-version 1
+version 3

Tabii ki, sadece yeni dosyalar eklemek için 'git add' yapmanın olağan tembel iş akışını takip etmemiz durumunda (bu durumda durum 1), yeni içeriklerin işlenerek güncellenmesi çok kritik değil. git commit -a Komut.


137
2018-05-18 18:05



Kesin olarak, git eklentiyle değiştirilen halihazırda hazırlanmış bir dosyayı kurmanın bir yolu var. Git ekledikçe, bu dosya için yalnızca bir dosyayı tamamen kaldırırken değil, yeni içerikle üzerine yazılırken de gevşek bir nesne olacak bir git nesnesi oluşturur. Ama otomatik olarak onu kurtarmak için bir komut yoktur. Bunun yerine, dosyanın manuel olarak veya sadece bu dava için yazılmış araçlarla tanımlanması ve çıkartılması gerekir (libgit2 buna izin verir). Ama bu sadece dosya çok önemli ve büyük ve önceki sürümü düzenleyerek yeniden inşa edilemez eğer ödeyecek. - Johannes Matokic
Kendimi düzeltmek için: Gevşek nesne dosyası bulunduğunda (oluşturma tarihi / zamanı gibi meta verileri kullanın) git cat-file içeriğini kurtarmak için kullanılabilir. - Johannes Matokic
Başka bir yolu sahnelenen ancak işlenmemiş ve üzerine yazılan değişiklikleri geri kazanma ör. bir diğeri git add üzerinden git fsck --unreachable Bu, ulaşılamaz olan tüm objeleri listeleyecektir. git show SHA-1_ID veya git fsck --lost-found bu olacak> sarkan nesneleri .git/lost-found/commit/ veya .git/lost-found/other/, türüne bağlı olarak. Ayrıca bakınız git fsck --help - iolsmit


git rm --cached . -r

geçerli dizininizden eklediğin her şeyi tekrar tekrar "ekleyemez"


85
2017-12-09 21:19



Her şeyi tek tek eklemek istemedim, sadece belirli bir dosya. - paxos1977
Daha önce herhangi bir işleminiz yoksa da yardımcı olur. Önceki taahhüdün yokluğunda, git reset HEAD <file> söyleyebilirim fatal: Failed to resolve 'HEAD' as a valid ref. - Priya Ranjan Singh
Hayır bu ekler bir silme Geçerli dizininizdeki her şeyin Sadece belirsiz değişikliklere çok farklı. - Mark Amery


Koşmak

git gui

ve tüm dosyaları el ile kaldırın veya tümünü seçip üzerine tıklayarak taahhütsüzlük buton.


77
2017-10-12 01:12



Evet bunu anladım. Sadece örtülü bir şekilde şunu söylemek istedim: "Sizin git-gui.... ":) - Alexander Suraphel
"Git-gui: komut bulunamadı" yazıyor. Bunun işe yaradığından emin değilim. - Parinda Rajapaksha


Git, akla gelebilecek her eylem için komutlara sahiptir, ancak işleri doğru yapmak için kapsamlı bilgiye ihtiyaç duyar ve bu nedenle en iyi karşı sezgiseldir ...

Daha önce ne yaptın:

  • Bir dosyayı değiştirdi ve kullandı git add .veya git add <file>.

Ne istiyorsunuz:

  • Dosyayı dizinden kaldırın, ancak sürümde saklayın ve çalışma kopyasındaki izin verilmeyen değişikliklerle birlikte bırakın:

    git reset head <file>
    
  • Dosyayı HEAD'den son durumuna sıfırlayın, değişiklikleri geri alıp dizinden kaldırın:

    # Think `svn revert <file>` IIRC.
    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>
    

    Bu yana gereklidir git reset --hard HEAD tek dosya ile çalışmayacak.

  • Kaldır <file> un-sürümlü dosyayı çalışma kopyasındaki değişikliklerle koruyarak dizin ve sürümden:

    git rm --cached <file>
    
  • Kaldır <file> çalışma kopyası ve sürümden tamamen:

    git rm <file>
    

73
2018-03-29 11:14



'Git sıfırlama başı <dosya>' ve 'git rm --cached <file> farkına katlanamıyorum. Açıklayabilir misin? - jeswang
@jeswang dosyaları ya 'bilinir' (bunlardaki değişiklikler izlenir.), ya da 'sürümlü' değildirler. reset head Geçerli değişikliklerinizi geri alır, ancak dosya hâlâ git tarafından izlenmektedir. rm --cached dosyayı sürümden çıkarır, böylece git artık değişiklikler için denetler (ve aynı zamanda önceki dizine gitmesi söylenen, endeksli mevcut değişiklikleri kaldırır) add), ancak değiştirilen dosya çalışma kopyanızda tutulacak, yani HDD'de dosya klasörünüzde. - sjas
Fark git reset HEAD <file> geçici - komut sadece bir sonraki işleme uygulanacak, ancak git rm --cached <file> ile tekrar eklenir git add <file>. Ayrıca, git rm --cached <file> Bu dalı uzaktan kumandaya geçirirseniz, şubeyi çeken herkes ACTUALLY klasöründen silinir. - DrewT