Git komutundan dosya kaldırma


1612

Git kullanıyorum ve birkaç dosya kullandım

git commit -a

Daha sonra, bir dosyanın yanlışlıkla işleme eklendiğini gördüm.

Bir dosyayı son işlemden nasıl kaldırabilirim?


2
Bu bağlantı sorunuz için mükemmel: stackoverflow.com/questions/307828/…
b3h3m0th

@CharlesB: evet, bu benim son görevim
Lolly

8
u sunucuya taahhüt itti?
Paritosh Singh

4
Ben sadece bunu kullanarak yapmak:git reset filepath
felipekm

Yanıtlar:


3088

Buradaki diğer cevapların yanlış olduğunu düşünüyorum, çünkü bu, yanlışlıkla yapılan dosyaları, önceki değişiklikleri izleyen bir aşamadan önceki aşamaya geri taşıma sorusudur. Bu Paritosh Singh'in önerdiği gibi yapılabilir:

git reset --soft HEAD^ 

veya

git reset --soft HEAD~1

Ardından, istenmeyen dosyaları taahhütten uzak tutmak için sıfırlayın:

git reset HEAD path/to/unwanted_file

Şimdi tekrar taahhüt edin, aynı taahhüt mesajını tekrar kullanabilirsiniz:

git commit -c ORIG_HEAD  

86
Bunun için teşekkürler. Daha önce (yanlış) taahhüdünüzü zaten ittiyseniz ve şimdi git pushrepolarınıza kadar düzeltmeye çalışıyorsanız, şikayet edeceğinizi eklemeye değer Updates were rejected because the tip of your current branch is behind its remote counterpart.. Onları itmek istediğinizden eminseniz (örneğin, çatalınız) -f, itmeyi zorlamak için seçeneği kullanabilirsiniz , örn git push origin master -f. (Bunu başkalarının getirdiği yukarı
yönlü bir repoya yapmayın

57
git reset --soft HEAD^en yaygın geri alma
işlemim

2
@PabloFernandez, her şeyden önce, kabul edilen cevap OP'nin aradığı şey olabilir (Ayrıca, aylar önce yayınlanmıştır). İkincisi, kabul edilen cevaplar, oyların sayısına bakılmaksızın her zaman en üsttedir.
MITjanitor

4
@PabloFernandez tüm cevapların üst kısmında cevapların sırasını kontrol etmenizi sağlayan üç sekme vardır: aktif , en eski ve oylar . Sanırım seninki en eskisine ayarlanmış . Bunu geçin oy kabul cevap hâlâ üstünde olacak olsa da, bu yanıtın ikinci olacak.
ahsteele

15
Bunu çok iyi biliyordum git resetama mevcut "mevcut" taahhüdü etkilemenin bir yolunu istedim. Az önce öğrendim git commit -C. Yani benim için istediğim, bir adım daha attığın tarifin "tekrar yeni taahhüt" olduğunu söyledi git commit -C [hash of original HEAD commit from first step].
metamatt

323

DİKKAT ! Bir dosyayı yalnızca önceki işleminizden kaldırmak ve diskte tutmak istiyorsanız, hemen yukarıdaki juzzlin'in cevabını okuyun .

Bu son işleminizse ve dosyayı yerel ve uzak depodan tamamen silmek istiyorsanız , şunları yapabilirsiniz:

  1. dosyayı kaldır git rm <file>
  2. değişiklik bayrağı ile taahhüt: git commit --amend

Değişiklik bayrağı git'e tekrar taahhütte bulunmasını söyler, fakat bu son taahhüdüyle "birleştirmeyi" (iki şubeyi birleştirmek anlamında değil).

Yorumlarda belirtildiği git rmgibi , burada kullanmak rmkomutun kendisini kullanmak gibidir !


120
git rm --cacheddosyaları diskte tutmak için de kullanabilirsiniz
Arkadiy Kukarkin

14
Bu yanıta göz atanlara uyarı: dosyayı yalnızca SİL listesinden kaldırmakla kalmayıp aynı zamanda silmek istediğinizden emin olun.
Scott Biggs

8
Başkalarının söylediklerini eklemek için (ve gerçekten istediğiniz sürece daha kolay bunu yapmak değil hatırlamak için): in komutasırmgit edilmektedir yapıyor rmkendisi yapar!
yo

@CharlesB Daha fazla görünürlük sağlamak için lütfen Arkadiy Kukarkin'in yorumundan gelen notu ekleyebilir misiniz?
mopo922

2
Fikrinizi değiştirmeniz durumunda dosyaların yine de geri yüklenebileceğini unutmayın. Daha önceki git commit --amendişlem hala oradadır ve örneğin ile bulunabilir git reflog. Yani diğer yorumların önerdiği kadar kötü değil.
Steohan

165

Mevcut cevaplar, istenmeyen dosyaları son işlemden kaldırmaktan bahsediyor .

İstenmeyen dosyaları eski bir işlemden (hatta zorla) kaldırmak istiyorsanız ve eylem nedeniyle gereksiz olan yeni bir işlem oluşturmak istemiyorsanız:

1.

Dosyanın uyumlu olmasını istediğiniz taahhüdü bulun.

git checkout <commit_id> <path_to_file>

çok sayıda dosyayı kaldırmak istiyorsanız bunu birkaç kez yapabilirsiniz.

2.

git commit -am "remove unwanted files"

3.

Dosyaların yanlışlıkla eklendiği taahhüdün command_id değerini bulun, burada "35c23c2" diyelim

git rebase 35c23c2~1 -i  // notice: "~1" is necessary

Bu komut düzenleyiciyi ayarlarınıza göre açar. Varsayılan değer vim'dir.

"İstenmeyen dosyaları kaldır" olması gereken son komutu, yanlış taahhüdün (bizim durumumuzda "35c23c2") sonraki satırına taşıyın ve komutu şu şekilde ayarlayın fixup:

pick 35c23c2 the first commit
fixup 0d78b28 remove unwanted files

Dosyayı kaydettikten sonra iyi olmalısınız.

Bitirmek için :

git push -f

Maalesef çatışma yaşarsanız, bunları manuel olarak çözmeniz gerekir.


2
Nano ile bunu yapmak muhteşem! Ctrl + K, Ctrl + U, bir 'f', Ctrl + X, 'y' ve voila koy!
sequielo

6
Dosyaları yalnızca önceki bir sürüme döndürmek yerine repodan (dosya sisteminden) kaldırmak istiyorsanız, adım 1 yerine yapın git rm --cached <file(s)>.
00'de kıvrımlı

2
Taahhütleri istediğiniz zaman interaktif rebase dosyasının etrafında taşıyabilirsiniz?
Dan Rosenstark

2
Tamamen yapabilirsin, ama çatışabilirsin (veya etmeyebilirsin).
Brian

6
Bu süreç ekleyerek biraz daha kolay yapılmış olabilir --fixup=35c23c2için git commitkomuta. Bu işlem, taahhüdü otomatik olarak gerekli işlemin bir düzeltmesi olarak ayarlayacaktır ve bu nedenle yeniden dağıtımda belirtmeniz gerekmez. Eklerseniz Ayrıca, --autosquashkarşı git rebasekomuta, git otomatik interaktif rebase içinde bir şey yapmanıza gerek kalmaz senin, doğru konuma taahhüt hareket edecek - sadece sonucu tasarrufu (hatta gerekmez anlamına gelen -ibayrak, Yine de her şeyi beklediğimden emin olmak için kullanmak istiyorum).
Guss

144

Kabul edilen yanıtın belirttiği gibi, bunu tüm taahhüdü sıfırlayarak yapabilirsiniz. Ancak bu oldukça ağır bir yaklaşımdır.
Bunu yapmanın daha temiz bir yolu, taahhüdü korumak ve değiştirilen dosyaları ondan kaldırmak olacaktır.

git reset HEAD^ -- path/to/file
git commit --amend --no-edit

git resetÖnceki olduğu gibi dosyayı koymak, kendini ve endeksinde bunu sahnelenecek. Çalışma dizinindeki dosyaya dokunulmaz. Daha sonra işlemek ve akıma endeksi taahhüt kabak olacaktır.
git commit

Bu, esasen önceki işlemde olan dosyanın sürümünü alır ve geçerli işleme ekler. Bu net bir değişiklik ile sonuçlanır ve böylece dosya kesin olarak etkili bir şekilde kaldırılır.


5
Bu, tüm taahhüdü elden geçirmeden tek bir dosyayı kaldırmak için çok daha iyi bir cevaptır.
16:16

Bu tam olarak bu cevapla aynı: D stackoverflow.com/a/27340569/1623984
ThatsAMorais

@ThatsAMorais gerçekten :-). Bu sorunun başka biriyle birleştirilip birleştirilmediğini merak ediyorum ve bu yüzden görmedim. Ya da belki sadece körüm. Her iki durumda da, sanırım daha popüler gibi görünen oylara dayanarak ayrılmaya meyilliyim (belki insanlar kısa ve doğrudan cevabı tercih ederler).
Patrick

Elbette bırakın! :) Doğru bir fikrimiz vardı ve amacı yardımcı olmak. Bence birleştirme iyi bir teori.
ThatsAMorais

Github'da bir şubeye ittiyseniz bunu nasıl yaparsınız? Bu düzeltmeyi yaptıktan sonra zorlamaya çalıştım ve "Güncel dalınızın ipucu ipucu arkasında olduğu için güncellemeler reddedildi: uzaktaki karşılığı."
Ollie Williams

41

Sunucudaki değişiklikleri itmediyseniz,

git reset --soft HEAD~1

Tüm değişiklikleri sıfırlayacak ve bir geri dönüşe geri dönecek

Değişikliklerinizi ittiyseniz, @CharlesB tarafından yanıtlanan adımları izleyin


2
-1 git reset dosyalama bölgesinden gelen değişiklikleri kaldırır, burada değişiklik yapılmıştır
CharlesB

Tamam, ama OP'nin istediği şey olmadığından aşağı notumu koruyacağım :) üzgünüm
CharlesB

tamam benim için iyi, ama neden rakip bunu istemiyor. Sorun nedir?
Paritosh Singh

büyük bir anlaşma değil, ama OP son dosyayı istemeden kaldırmak istediği için ve sadece taahhütte bulunmadan önce devlete sıfırlar. hala taahhüdü yeniden yapmalısın.
CharlesB

3
@Aris, değişiklikleri görmek için <git diff --cached> kullan
Paritosh Singh

37

Rm kullanarak dosyayı kaldırmak dosyayı silecektir!

Her zaman git yerine bir taahhüdüne ekleme yapıyorsunuz, bu nedenle dosyayı ilk işlemden önceki durumuna geri döndürün (dosya yeni ise bu bir 'rm' silme işlemi olabilir) ve sonra yeniden taahhüt ve dosya gidecek.

Dosyayı önceki bir duruma geri döndürmek için:

    git checkout <commit_id> <path_to_file>

veya uzak KAFA'daki duruma geri döndürmek için:

    git checkout origin/master <path_to_file>

sonra taahhüdü değiştirin ve dosyanın listeden kaybolduğunu görmelisiniz (ve diskinizden silinmez!)


36
git checkout HEAD~ path/to/file
git commit --amend

1
Bu, son işlemi, itilmemiş olanı değiştirmenin en iyi yoludur. Bu, bir dosyadaki değişiklikleri sıfırlar ve bu dosyayı son işlemden etkili bir şekilde kaldırır.
Alex Bravo

Bu da dosyayı değiştirdi. Dosyadaki yerel değişiklikler nasıl korunur?
theonlygusti

29

Aşağıdakiler yalnızca OP'nin istediği dosyayı bozar.

git reset HEAD^ /path/to/file

Aşağıdaki gibi bir şey göreceksiniz ...

Taahhüt edilecek değişiklikler: (değişmeden "git reset HEAD ..." kullanın)

değiştirildi: / path / to / file

Taahhüt için değiştirilmeyen değişiklikler: (taahhüt edilenleri güncellemek için "git add ..." kullanın) (çalışma dizinindeki değişiklikleri atmak için "git checkout - ..." kullanın)

değiştirildi: / path / to / file

  • "Taahhüt edilecek değişiklikler", dosyanın taahhütten önceki önceki sürümüdür. Dosya hiç mevcut değilse bu bir silme gibi görünecektir. Bu değişikliği yaparsanız, değişikliği dalınızdaki dosyaya geri döndüren bir düzeltme yapılır.
  • "Taahhüt için aşamalı olmayan değişiklikler", taahhüt ettiğiniz değişiklik ve dosyanın geçerli durumu

Bu noktada, farklı bir sürüme sıfırlama gibi dosyayı istediğiniz her şeyi yapabilirsiniz.

Taahhüt etmeye hazır olduğunuzda:

git commit --amend -a

veya (henüz taahhüt etmek istemediğiniz başka değişiklikler varsa)

git commit add /path/to/file
git commit --amend

3
juzzlin'in cevabı harika, ama sadece bir tanesini bozmak istediğinizde tüm taahhüdü bozmak aşırı. Komutun tümünün kaldırılması, kaybetmek istemediğiniz dosyadaki şu anda değişmemiş değişiklikleriniz varsa sorunlara neden olabilir.
14:16

27

Size örnekle anlatacağım.
A, B, C 3 ardışık taahhüt olsun. Taahhüt B, işlenmemiş olması gereken bir dosya içerir.

git log  # take A commit_id
git rebase -i "A_commit_ID" # do an interactive rebase
change commit to 'e' in rebase vim # means commit will be edited
git rm unwanted_file
git rebase --continue
git push --force-with-lease <branchName>    

Belirli bir dosya son veya önceki işlemde değilse, bu en zarif yoldur. Hatta genel olarak en zarif yol olduğunu bile söyleyebilirim. Etkileşimli yeniden temellendirmeyi seviyorum.
bvgheluwe

Tek bir taahhüt noopiçin edit [A_commit_ID]veya olarak değiştirine [A_commit_ID]
TamusJRoyce

23

Sadece deneyebilirsiniz.

git reset --soft HEAD~1

ve yeni bir taahhüt oluşturun.

Ancak, harika bir yazılım "gitkraken" var. git ile çalışmayı kolaylaştırır.


1
Ve sadece not etmek için: Bundan sonra git commit --amend, dosya kaldırma işleminin son işleminizde güncellenmesini sağlamanız gerekir; ve daha sonra, gerçekten kaldırıldığını kontrol edebilirsinizgit log -1 --stat
sdbbs

13
git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "removed unwanted file from git"

size yerel dosyayı hala bırakacaktır. Dosyayı yerel olarak da istemiyorsanız, --cached seçeneğini atlayabilirsiniz.

Tüm işler yerel şubenizde ise, dosyayı daha sonraki bir taahhütte tutmanız gerekir ve temiz bir geçmişe sahip olmak gibi, bunu yapmanın daha basit bir yolu olabilir:

git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit --squash <commit_id>
git add <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "brand new file!"
git rebase --interactive <commit_id>^

ve daha karmaşık komutları hatırlamak veya mesaj veya yazı yazmak zorunda kalmadan rebase'i kolayca bitirebilirsiniz.


Bu benim için çalışıyor. Dosyaları tekrar karışıma eklemek istiyorsanız, sadece git add -A veya git add kullanın. ve geri döndüler.
Alexander Mills

11

Git GUI'yi kullanmak, bir dosyayı önceki işlemden kaldırmayı basitleştirebilir.

Bunun paylaşılan bir şube olmadığını ve geçmişi yeniden yazmanın sakıncası olmadığını varsayarak çalıştırın:

git gui citool --amend

Yanlışlıkla taahhüt edilen dosyanın işaretini kaldırabilir ve ardından "Tamamla" yı tıklayabilirsiniz.

resim açıklamasını buraya girin

Dosya, işlemden kaldırılır, ancak diskte tutulur . Yanlışlıkla ekledikten sonra dosyanın işaretini kaldırırsanız, izlenmeyen dosyalar listenizde gösterilir (ve yanlışlıkla değiştirdikten sonra dosyanın işaretini kaldırırsanız, değişiklik listesi için hazırlanmayan değişikliklerinizde gösterilir).


2
Ubuntu'da, git sudo apt-get install git-gui
gui'yi

Teşekkür ederim! Bir .git repo içeren bir klasör eklendi bir sorun (hata?) İle sıkışmış ve tüm normal kaldırma komutları işe yaramadı. Ancak bu yardımcı oldu. Birkaç taahhütte bulundum, önce editör'ü git rebase -i HEAD~4açmak için komutunu kullandım. Başka bir not: "Kararsızlık", "Tamam" menüsünde bulunabilir.
Johny Skovdal

En kolay çözüm. Hatırlaması en kolay. Ve git reset --soft HEAD^(--soft arg öğesini hatırlamak) ve ardından git commit -c ORIG_HEAD(her şeyi berbat eden --amend yerine ) hatadan daha az eğilimli .
Brent Faust

9

Taahhütünüzü korumak istiyorsanız (belki de ayrıntılı bir tamamlama mesajı yazmak için biraz zaman harcadınız ve kaybetmek istemiyorsanız) ve dosyayı yalnızca taahhütten kaldırmak, ancak depodan tamamen kaldırmak istiyorsanız:

git checkout origin/<remote-branch> <filename>
git commit --amend

6

Aşağıdaki komutların bir sırasını yapın:

//to remove the last commit, but preserve changes  
git reset --soft HEAD~1

//to remove unneded file from the staging area  
git reset HEAD `<your file>` 

//finally make a new commit  
git commit -m 'Your message'

Bu adımları yapmaya çalıştım ve bu hata hatasını görüyorum: 'git ....' için bazı referanslar gönderilemedi. Geçmişinizi kaybetmenizi önlemek için, hızlı ilerlemeyen güncellemeler reddedildi Uzaktan değişiklikleri birleştirin (ör. 'git pull'). Ayrıntılar için 'git push --help'in' Hızlı ileri sarma hakkında not 'bölümüne bakın. (git pull sonra aynı değişiklikleri var)
Dezigo

Bu, yerel işinizi yaparken uzak repo durumunuzun değiştiği anlamına gelir. Ve 'git pull' işleminden sonra, yerel değişiklikleriniz uzaktaki değişikliklerle birleştirilmelidir, hepsi bu. Elbette, değişiklikleriniz kalmalıdır.
Sergey Onishchenko

Diğer bir deyişle, @Dezigo hatasını alırsanız, güncellemeyi zorlamak için -f bayrağını ekleyin.
jungledev

5

Sadece ekstra bir komut çalıştırmak zorunda gibi üst cevabı tamamlamak istedim:

git reset --soft HEAD^
git checkout origin/master <filepath>

Şerefe!


Hoşgeldiniz. Komutların gerçekte ne yaptığını açıklarsanız bu cevap daha iyi olurdu.
Mark Chorley

3

Benim için işe yarayan, ancak yine de daha iyi bir çözüm olması gerektiğini düşünen bir şey:

$ git revert <commit_id>
$ git reset HEAD~1 --hard

Atmak istediğiniz değişikliği diğer taahhütte bırakın, diğerlerine göz atın

$ git commit --amend // or stash and rebase to <commit_id> to amend changes

3

git reset --soft HEAD^taahhüdünüzü geri sarar ve yazdığınızda size ne yapmanız git statusgerektiğini söyler:

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

2

Aslında, git rebase etkileşimli modunu kullanmak için daha hızlı ve daha kolay bir yol olduğunu düşünüyorum.

git rebase -i head~1  

(ya da ~ 4 kafa, ne kadar ileri gitmek istersen)

ve sonra "al" yerine "düzenle" yi kullanın. 'Düzenlemenin' ne kadar güçlü olduğunun farkında değildim.

https://www.youtube.com/watch?v=2dQosJaLN18

Umarım faydalı bulacaksınız.


video 10 dakika sürüyor ve kullanışlı değil
MolbOrg

2

Ben sadece bir dosyaya geri dönmek istedim yerel bir şube değişiklikleri var aynı sorunu vardı. Benim için işe yarayan -

( aşağıdaki özellik / target_branch , belirli bir dosya için geri almak istediğim değişiklikler dahil tüm değişikliklerimin olduğu yerdir)

( origin / feature / target_branch yaptığım değişiklikleri göndermek istediğim uzak dal)

( özellik / aşamalandırma , bu dosyadaki değişiklik hariç tüm istediğim değişikliklerden zorlayacağım geçici aşamalandırma dalıdır)

  1. Başlangıç ​​/ özellik / target_branch'ımdan yerel bir dal oluştur - buna özellik / aşamalandırma adı verildi

  2. Benim çalışma yerel şube Birleştirilmiş özellik / target_branch için özellik / evreleme şube

  3. Teslim edilen özellik / evreleme sonra git reset --soft ORIG_HEAD (Şimdi özellik / evreleme'deki tüm değişiklikler aşamalı olacak, ancak kullanılmayacak.)

  4. Gereksiz değişikliklerle daha önce iade ettiğim dosyanın etiketsiz

  5. Özellik / evreleme için yukarı akış dalı başlangıç ​​noktasına / özellik / target_branch olarak değiştirildi

  6. Aşamalı değişikliklerin geri kalanını taahhüt ettim ve uzak kökeni / özelliği / target_branch'ımın yukarısına itti


1

Eğer bu dosyaya artık ihtiyacınız yoksa,

git rm file
git commit --amend
git push origin branch

1

GitHub kullanıyorsanız ve henüz taahhütte bulunmadıysanız, GitHub Desktop bu sorunu kolayca çözer:

  1. Depo -> En Son İşlemleri Geri Al'ı seçin
  2. Yanlışlıkla eklediğiniz dosyanın seçimini kaldırın. Önceki tamamlama mesajınız zaten iletişim kutusunda olacaktır.
  3. Tamam düğmesine basın!

1

Önceki işlemlerden dosyaları kaldırmak istiyorsanız filtreleri kullanın

git filter-branch --prune-empty --index-filter 'git rm --ignore-unmatch --cached "file_to_be_removed.dmg"'

Bu hatayı görürseniz:

Yeni bir yedek oluşturulamıyor. Refs / original / -f ile yedeğin üzerine yazmayı zorla seçeneğinde önceki bir yedekleme zaten var

Yerel deponuzdaki refs yedeklerini kaldırmanız yeterli

$ rm -rf .git/refs/original/refs

1

eğer değişikliklerinizi henüz git'e itmezseniz

git reset --soft HEAD~1

Tüm değişiklikleri sıfırlayacak ve bir geri dönüşe geri dönecek

Son yaptığınız işlem buysa ve dosyayı yerel ve uzak depodan silmek istiyorsanız şunu deneyin:

git rm <file>
 git commit --amend

veya daha iyisi:

önce sıfırla

git reset --soft HEAD~1

istenmeyen dosyayı sıfırla

git reset HEAD path/to/unwanted_file

tekrar taahhüt et

git commit -c ORIG_HEAD  

yukarıdaki ile aynı ama gerçekten çapraz kontrol etmek için yardımcı oldu
Reshma

0

Bu benim için dosyayı başlangıçta şubeye itti bit kova repo kaldırmak için çalıştı.

git checkout origin/develop <path-to-file>
git add <path-to-file>
git commit -m "Message"
git push

0

Geçerli dosyaları farklı bir klasöre kopyaladım, sonra tüm unpushed değişikliklerinden kurtuldum:

git reset --hard @{u}

Sonra işleri geri kopyalayın. Yapma, İtme.


0

Bu komutu kullanabilirsiniz:

git restore --staged <file>

0
Here is the step to remove files from Git Commit.

>git reset --soft HEAD^1(either commitid ) -- now files moved to the staging area.
>git rm --cached filename(it will removed the file from staging area)
>git commit -m 'meaningfull message'(Now commit the required files)

-1

Şu anda cevapların hiçbiri makul değil. Gerçek bir çözüm önerilmesi için yeterli talep olduğu anlaşılıyor: https://github.com/git/git/blob/master/Documentation/SubmittingPatches

git --uncommit <dosya adı>

güzel olurdu. Geçmişi değiştirmek istemediğimi anlıyorum, ancak yerel ve yanlışlıkla yerel "hack" dosyasını eklediğimde ve taahhütten kaldırmak istiyorsanız bu süper yararlı olacaktır.

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.