Sto usando Git e ho commesso alcuni file usando
git commit -a
Successivamente, ho scoperto che un file era stato erroneamente aggiunto al commit.
Come posso rimuovere un file dall'ultimo commit?
git reset filepath
Sto usando Git e ho commesso alcuni file usando
git commit -a
Successivamente, ho scoperto che un file era stato erroneamente aggiunto al commit.
Come posso rimuovere un file dall'ultimo commit?
git reset filepath
Risposte:
Penso che altre risposte qui siano sbagliate, perché si tratta di spostare i file commessi per errore nell'area di gestione temporanea dal commit precedente, senza annullare le modifiche apportate. Questo può essere fatto come suggerito da Paritosh Singh:
git reset --soft HEAD^
o
git reset --soft HEAD~1
Quindi reimpostare i file indesiderati per lasciarli fuori dal commit:
git reset HEAD path/to/unwanted_file
Ora esegui nuovamente il commit, puoi persino riutilizzare lo stesso messaggio di commit:
git commit -c ORIG_HEAD
git push
correggere il tuo repository, si lamenterà Updates were rejected because the tip of your current branch is behind its remote counterpart.
. Se sei sicuro di voler spingerli (ad es. È la tua forcella), puoi usare l' -f
opzione per forzare la spinta, ad es git push origin master -f
. (Non eseguire questa operazione in un repository upstream da cui altri stanno recuperando)
git reset --soft HEAD^
è la mia operazione di annullamento più comune
git reset
ma volevo un modo per influenzare il commit esistente "sul posto". Ho appena saputo git commit -C
. Quindi per me, quello che voglio è la tua ricetta esatta con un altro passo, il "nuovo impegno di nuovo" spiegato come git commit -C [hash of original HEAD commit from first step]
.
ATTENZIONE ! Se vuoi solo rimuovere un file dal tuo precedente commit e tenerlo su disco , leggi la risposta di juzzlin appena sopra.
Se questo è il tuo ultimo commit e desideri eliminare completamente il file dal tuo repository locale e remoto , puoi:
git rm <file>
git commit --amend
Il flag di modifica dice a git di eseguire nuovamente il commit, ma "unisci" (non nel senso di unire due rami) questo commit con l'ultimo commit.
Come indicato nei commenti, usare git rm
qui è come usare il rm
comando stesso!
git rm --cached
per mantenere i file su disco
rm
nel git
comando di sta facendo quello rm
sé!
git commit --amend
è ancora lì e può essere trovato ad esempio con git reflog
. Quindi non è così male come suggeriscono gli altri commenti.
Le risposte esistenti parlano tutte della rimozione dei file indesiderati dall'ultimo commit.
Se si desidera rimuovere file indesiderati da un vecchio commit (anche push) e non si desidera creare un nuovo commit, che non è necessario, a causa dell'azione:
1.
Trova il commit a cui desideri che il file sia conforme.
git checkout <commit_id> <path_to_file>
puoi farlo più volte se vuoi rimuovere molti file.
2.
git commit -am "remove unwanted files"
3.
Trova il commit_id del commit su cui i file sono stati aggiunti per errore , diciamo "35c23c2" qui
git rebase 35c23c2~1 -i // notice: "~1" is necessary
Questo comando apre l'editor in base alle tue impostazioni. Quello predefinito è vim.
Spostare l'ultimo commit, che dovrebbe essere "rimuovi file indesiderati", sulla riga successiva del commit errato ("35c23c2" nel nostro caso) e impostare il comando come fixup
:
pick 35c23c2 the first commit
fixup 0d78b28 remove unwanted files
Dovresti essere bravo dopo aver salvato il file.
Finire :
git push -f
Se purtroppo si verificano conflitti, è necessario risolverli manualmente.
git rm --cached <file(s)>
.
--fixup=35c23c2
al git commit
comando. Ciò imposterà automaticamente il commit come correzione del commit richiesto e quindi non sarà necessario specificarlo nel rebase. Inoltre, se aggiungi --autosquash
al git rebase
comando, git sposterà automaticamente il commit nella posizione corretta, quindi non devi fare nulla nel rebase interattivo - salva semplicemente il risultato (il che significa che non devi nemmeno -i
contrassegnare, anche se mi piace usarlo comunque per assicurarmi che tutto appaia come mi aspetto).
Come indica la risposta accettata, è possibile farlo ripristinando l'intero commit. Ma questo è un approccio piuttosto pesante.
Un modo più pulito per farlo sarebbe quello di mantenere il commit e rimuovere semplicemente i file modificati da esso.
git reset HEAD^ -- path/to/file
git commit --amend --no-edit
Il git reset
prenderà il file come era nel precedente commit, e la fase è nell'indice. Il file nella directory di lavoro non è stato toccato.
Il git commit
sarà poi impegnarsi e schiacciare l'indice nella corrente commesso.
Questo essenzialmente prende la versione del file che era nel commit precedente e lo aggiunge al commit corrente. Ciò non comporta alcuna variazione netta e quindi il file viene effettivamente rimosso dal commit.
Se non è stato eseguito il push delle modifiche sul server, è possibile utilizzare
git reset --soft HEAD~1
Ripristinerà tutte le modifiche e tornerà a un commit indietro
Se hai apportato le modifiche, segui i passaggi indicati da @CharlesB
Rimuovere il file usando rm lo cancellerà!
Stai sempre aggiungendo a un commit in git piuttosto che rimuoverlo, quindi in questo caso riporta il file allo stato in cui si trovava prima del primo commit (potrebbe essere un'azione 'rm' di cancellazione se il file è nuovo) e quindi ripetere il commit e il file andrà.
Per riportare il file in uno stato precedente:
git checkout <commit_id> <path_to_file>
o per riportarlo allo stato sul HEAD remoto:
git checkout origin/master <path_to_file>
quindi modifica il commit e dovresti trovare il file scomparso dall'elenco (e non cancellato dal tuo disco!)
git checkout HEAD~ path/to/file
git commit --amend
Quanto segue rimuoverà in scena solo il file desiderato, che è ciò che l'OP ha chiesto.
git reset HEAD^ /path/to/file
Vedrai qualcosa di simile al seguente ...
Modifiche da impegnare: (utilizzare "git reset HEAD ..." per annullare la messa in scena)
modificato: / percorso / in / file
Modifiche non messe in scena per il commit: (usa "git add ..." per aggiornare ciò che verrà eseguito il commit) (usa "git checkout - ..." per scartare le modifiche nella directory di lavoro)
modificato: / percorso / in / file
A questo punto, puoi fare quello che vuoi sul file, come ripristinare una versione diversa.
Quando sei pronto a impegnarti:
git commit --amend -a
oppure (se hai in corso altre modifiche che non vuoi ancora impegnare)
git commit add /path/to/file
git commit --amend
Ti spiegherò con un esempio.
Sia A, B, C 3 commit successivi. Commit B contiene un file che non avrebbe dovuto essere eseguito il commit.
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>
noop
passa a edit [A_commit_ID]
oe [A_commit_ID]
Puoi semplicemente provare.
git reset --soft HEAD~1
e creare un nuovo commit.
Tuttavia, esiste un fantastico software "gitkraken". che rende facile lavorare con git.
git commit --amend
per avere la rimozione del file aggiornata nell'ultimo commit; e successivamente, puoi verificare che sia stato effettivamente rimosso congit log -1 --stat
git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "removed unwanted file from git"
ti lascerà il file locale ancora. Se non vuoi neanche il file localmente, puoi saltare l'opzione --cached.
Se tutto il lavoro è sul tuo ramo locale, devi conservare il file in un commit successivo e, come avere una cronologia pulita, penso che un modo più semplice per farlo potrebbe essere:
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>^
e puoi quindi terminare il rebase con facilità senza dover ricordare comandi più complessi o eseguire il commit di messaggi o digitare altrettanto.
L'uso di git GUI può semplificare la rimozione di un file dal commit precedente.
Supponendo che questo non sia un ramo condiviso e non ti dispiaccia riscrivere la cronologia , quindi esegui:
git gui citool --amend
È possibile deselezionare il file commesso per errore e quindi fare clic su "Conferma".
Il file viene rimosso dal commit, ma verrà mantenuto sul disco . Quindi, se hai deselezionato il file dopo averlo erroneamente aggiunto, verrà visualizzato nell'elenco dei file non monitorati (e se hai deselezionato il file dopo averlo modificato erroneamente, verrà visualizzato nelle modifiche non messe in scena per l'elenco di commit).
sudo apt-get install git-gui
git rebase -i HEAD~4
e poi ho eseguito il tuo comando per aprire l'editor. Un'altra nota: "Unstaging" è disponibile nel menu "Commit".
git reset --soft HEAD^
(ricordando --soft arg), seguito da git commit -c ORIG_HEAD
(piuttosto che --amend, che rovina tutto).
Se vuoi conservare il tuo commit (forse hai già trascorso un po 'di tempo a scrivere un messaggio di commit dettagliato e non vuoi perderlo), e vuoi solo rimuovere il file dal commit, ma non dal repository interamente:
git checkout origin/<remote-branch> <filename>
git commit --amend
Esegui una sequenza dei seguenti comandi:
//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'
Volevo solo integrare la risposta migliore in quanto dovevo eseguire un comando aggiuntivo:
git reset --soft HEAD^
git checkout origin/master <filepath>
Saluti!
Qualcosa che ha funzionato per me, ma penso ancora che ci dovrebbe essere una soluzione migliore:
$ git revert <commit_id>
$ git reset HEAD~1 --hard
Lascia la modifica che desideri annullare nell'altro commit, controlla gli altri
$ git commit --amend // or stash and rebase to <commit_id> to amend changes
In realtà, penso che un modo più rapido e semplice sia usare la modalità interattiva git rebase.
git rebase -i head~1
(o testa ~ 4, quanto lontano vuoi andare)
e poi, invece di 'pick', usa 'edit'. Non mi rendevo conto di quanto fosse potente "modifica".
https://www.youtube.com/watch?v=2dQosJaLN18
Spero che lo troverai utile.
Ho avuto lo stesso problema in cui ho apportato modifiche in una filiale locale in cui volevo ripristinare solo un file. Ciò che ha funzionato per me è stato -
( feature / target_branch di seguito è dove ho tutte le mie modifiche, comprese quelle che volevo annullare per un file specifico)
( origin / feature / target_branch è il ramo remoto in cui voglio inviare le mie modifiche)
( caratteristica / messa in scena è il mio ramo di gestione temporanea in cui spingerò da tutte le mie modifiche desiderate escludendo la modifica a quel file)
Crea un ramo locale dalla mia origine / funzionalità / target_branch - chiamato funzione / messa in scena
Ho unito la mia funzione di filiale locale funzionante / target_branch al ramo di funzionalità / stadiazione
Il check-out caratteristica / staging poi ripristinato git ORIG_HEAD --soft (Ora tutte le modifiche dalla funzione / messa in scena' andrà in scena, ma non impegnati.)
Non messo in scena il file che ho precedentemente archiviato con modifiche non necessarie
Modificato il ramo upstream per feature / staging in origin / feature / target_branch
Commesso il resto delle modifiche organizzate e spinto a monte verso la mia origine / funzione / target_branch remota
Se stai usando GitHub e non hai ancora eseguito il commit, GitHub Desktop risolve facilmente questo problema:
Se si desidera rimuovere file da precedenti commit utilizzare i filtri
git filter-branch --prune-empty --index-filter 'git rm --ignore-unmatch --cached "file_to_be_removed.dmg"'
Se vedi questo errore:
Impossibile creare un nuovo backup. Esiste già un backup precedente in refs / original / Force che sovrascrive il backup con -f
Basta rimuovere i backup refs sul repository locale
$ rm -rf .git/refs/original/refs
se non spingi ancora le tue modifiche su git
git reset --soft HEAD~1
Ripristinerà tutte le modifiche e tornerà a un commit indietro
Se questo è l'ultimo commit che hai fatto e vuoi eliminare il file dal repository locale e remoto prova questo:
git rm <file>
git commit --amend
o anche meglio:
reimpostare prima
git reset --soft HEAD~1
reimpostare il file indesiderato
git reset HEAD path/to/unwanted_file
impegnarsi di nuovo
git commit -c ORIG_HEAD
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)
Nessuna delle risposte in questo momento è ragionevole. Sembra che ci sia abbastanza richiesta per proporre una soluzione reale: https://github.com/git/git/blob/master/Documentation/SubmittingPatches
git --uncommit <nome file>
sarebbe bello. Capisco che non vogliamo modificare la cronologia, ma se sono locale e ho accidentalmente aggiunto il file locale "hack" locale e voglio rimuoverlo dal commit, ciò sarebbe di grande aiuto.