2010-06-30 15 views
7

ho fatto 2 commit (E non ho spinto) in git, dove 'Commit 2' è la più recente ':Come posso ripristinare 1 modifica di file nel mio precedente impegno

git log -2 
commit 791962d776f66253d656586b097b2677eaa983d1 
Author: michael <[email protected](none)> 
Date: Tue Jun 29 23:20:58 2010 -0700 

    Commit 2 

commit b743075e81f6fe25fe48ddbef2b5e7cc06623533 
Author: michael <[email protected](none)> 
Date: Tue Feb 16 23:09:53 2010 -0800 

    Commit 1 

E nel mio commettere 1 b743075e81f6fe25fe48ddbef2b5e7cc06623533, ho toccato/cambiato un certo numero di file:

dir1/file1.cpp 
    dir1/file1.h 
    dir1/file2.cpp 
    dir1/file2.h 

le mie domande è, come posso ripristinare i miei cambiamenti che ho fatto a dir1/file2.cpp, dir1/file2.h di commit 1? E mantenere tutto il resto lo stesso?

Grazie.

risposta

5

La soluzione più semplice sarebbe, dal tuo ultimo commit (HEAD) a:

  • checkout questi due file alla versione precedente,
  • aggiungerli,
  • e quindi eseguire il commit.
 
    git checkout b743075e81 -- dir1/file2.cpp 
    git checkout b743075e81 -- dir1/file2.h 
    git add dir1/file2.cpp # only if you made additional changes 
    git add dir1/file2.h # only if you made additional changes 
    git commit -m "revert dir1/file2.cpp and dir1/file2.h" 

Come Chris Johnsen menzioni nei commenti:

git checkout con pathspecs aggiorna l'indice (come git reset con pathspecs) e l'albero di lavoro, in modo da git add non è necessaria a meno che ulteriori modifiche sono fatto dopo il checkout.

+0

Questa è infatti la tua unica opzione sensata, se hai già usato 'git push' per spingere i tuoi commit all'origine. –

+0

* git checkout * con pathspecs aggiorna l'indice (come * git reset * con pathspecs) e l'albero di lavoro, quindi * git add * non è necessario a meno che non vengano apportate ulteriori modifiche dopo il checkout. –

+0

Non ho fatto una "git push". – michael

0

Usa seguente comando per ripristinare il file con file precedentemente impegnato in base alla hash commit e il nome del file che è necessario ripristinare

git reset <commit hash> <filename> 

Per l'utilizzo requisito

git reset b743075e81f6fe25fe48ddbef2b5e7cc06623533 dir1/file2.cpp 

git reset b743075e81f6fe25fe48ddbef2b5e7cc06623533 dir1/file2.h 
+0

Funziona, ma può essere fonte di confusione perché "restituisce" solo le voci dell'indice, non l'albero di lavoro (diversamente da 'git checkout treeish - pathspecs' che aggiorna sia l'indice che l'albero di lavoro). –

3

Se hai già spinto i tuoi commit all'origine, quindi le altre soluzioni descritte qui (usando git reset o git checkout, seguito da git commit) è la tua unica opzione .

Tuttavia, se non avete ancora spinto le modifiche, e si desidera rimuovere tutte le tracce che i file sono stati sempre impegnati, un rebase interattivo è una buona opzione. Utilizzare il seguente comando per rebase vostri ultimi due commit:

git rebase --interactive HEAD~2 

Un editore si aprirà, mostrando le vostre due commit. Si desidera modificare il file per mostrare quanto segue, quindi salvare; in particolare, si desidera modificare pick davanti al primo impegnarsi a edit:

edit b743075 Commit 1 
pick 791962d Commit 2 

Git sarà poi ci riporre in uno stato in cui siamo in grado di modificare il primo commit (senza toccare il secondo).Si dice che si può modificare il commit con git commit --amend, ma in realtà vuole fare un reset per il commit prima che la testa, e annullare del tutto:

git reset HEAD^ 

Questo metterà le modifiche dal Commit 1 nel vostro albero di lavoro. Poi, git add solo i file che si desidera conservare, e ri-commit utilizzando git commit:

git add dir1/file1.cpp 
git add dir1/file1.h 
git commit -m "Commit 1" 

Infine, fare un hard reset per eliminare i file che non si desidera mantenere dal vostro albero di lavoro, e la finitura il rebase:

git reset --hard 
git rebase --continue 

Quando il rebase è completo, il repository avrà entrambi i commit, ma nessuna traccia dei file file2.*.

Problemi correlati