Vraag Zoek en herstel een verwijderd bestand in een Git-repository


Stel dat ik in een Git-repository ben. Ik verwijder een bestand en voer die wijziging uit. Ik blijf werken en maak wat meer commits. Dan merk ik dat ik dat bestand moet herstellen.

Ik weet dat ik een bestand kan uitchecken met git checkout HEAD^ foo.bar, maar ik weet niet echt wanneer dat bestand is verwijderd.

  1. Wat is de snelste manier om de commit te vinden die een bepaalde bestandsnaam heeft verwijderd?
  2. Wat zou de gemakkelijkste manier zijn om dat bestand terug te krijgen in mijn werkkopie?

Ik hoop dat ik niet handmatig in mijn logboeken hoeft te bladeren, het hele project moet uitchecken voor een bepaalde SHA en dat bestand dan handmatig moet kopiëren naar mijn oorspronkelijke projectafhandeling.


2382
2018-06-04 22:40


oorsprong


antwoorden:


Zoek de laatste commit die het gegeven pad heeft beïnvloed. Omdat het bestand zich niet in de HEAD commit bevindt, moet deze commit het hebben verwijderd.

git rev-list -n 1 HEAD -- <file_path>

Check vervolgens de versie op de commit eerder, gebruik de caret (^) symbool:

git checkout <deleting_commit>^ -- <file_path>

Of in één opdracht, als $file is het bestand in kwestie.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

Als u zsh gebruikt en de EXTENDED_GLOB-optie ingeschakeld heeft, zal het caret-symbool niet werken. Je kunt gebruiken ~1 in plaats daarvan.

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"

2718
2017-07-11 07:12



  1. Gebruik git log --diff-filter=D --summary om alle commits te krijgen die verwijderde bestanden hebben en de bestanden zijn verwijderd;
  2. Gebruik git checkout $commit~1 filename om het verwijderde bestand te herstellen.

Waar $commit is de waarde van de commit die je hebt gevonden in stap 1, bijvoorbeeld e4cf499627


723
2018-06-04 23:10



Om al die verwijderde bestanden in een map te herstellen, voert u de volgende opdracht in.

git ls-files -d | xargs git checkout --

301
2017-12-02 06:11



Ik kwam naar deze vraag om een ​​bestand te herstellen dat ik zojuist heb verwijderd, maar ik had de wijziging nog niet doorgevoerd. Voor het geval u zich in deze situatie bevindt, hoeft u alleen maar het volgende te doen:

git checkout HEAD -- path/to/file.ext


99
2018-04-10 00:03



Als je gestoord bent, gebruik dan git-bisect. Hier is wat te doen:

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>

Nu is het tijd om de geautomatiseerde test uit te voeren. Het shell-commando '[ -e foo.bar ]' zal 0 retourneren als foo.bar bestaat, en 1 anders. Het commando "run" van git-bisect zal binaire zoekactie gebruiken om automatisch de eerste commit te vinden waar de test faalt. Het begint halverwege het gegeven bereik (van goed naar slecht) en snijdt het in tweeën op basis van het resultaat van de opgegeven test.

git bisect run '[ -e foo.bar ]'

Nu bent u bij de commit die het heeft verwijderd. Vanaf hier kunt u terug naar de toekomst springen en gebruiken git-revert om de wijziging ongedaan te maken,

git bisect reset
git revert <the offending commit>

of je zou een commit terug kunnen gaan en de schade handmatig kunnen inspecteren:

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .

82
2018-06-04 22:46



Mijn nieuwe favoriete alias, gebaseerd op bonyiii's antwoord (upvoted), en mijn eigen antwoord over "Geef een argument door aan een Git alias-commando":

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'

Ik ben een bestand kwijtgeraakt, per ongeluk een paar commits geleden verwijderd?
Snel:

git restore my_deleted_file

Crisis afgewend.


Robert Dailey stelt in de reacties de volgende alias:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

En Jegan voegt in de reacties:

Voor het instellen van de alias vanaf de opdrachtregel, heb ik deze opdracht gebruikt:

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 

61
2018-02-17 15:33



Als u de bestandsnaam kent, is dit een eenvoudige manier met basisopdrachten:

Maak een lijst van alle commits voor dat bestand.

git log -- path/to/file

De laatste commit (bovenste) is degene die het bestand heeft verwijderd. Dus je moet de voorlaatste commit herstellen.

git checkout {second to last commit} -- path/to/file

42
2018-02-27 01:50



Om een ​​verwijderd en vastgelegd bestand te herstellen:

git reset HEAD some/path
git checkout -- some/path

Het werd getest op Git versie 1.7.5.4.


27
2017-07-04 04:39



Als je alleen wijzigingen hebt aangebracht en een bestand hebt verwijderd, maar het niet hebt vastgelegd, en nu heb je het uitgemaakt met je wijzigingen

git checkout -- .

maar je verwijderde bestanden zijn niet teruggekomen, je doet simpelweg de volgende opdracht:

git checkout <file_path>

En presto, je bestand is terug.


21
2017-09-02 15:30



ik heb deze oplossing.

  1. Download de id van de commit waar het bestand is verwijderd met een van de onderstaande manieren.

    • git log --grep=*word* 
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* # aanbevolen als je nauwelijks onthoud alles
  2. Je zou iets moeten krijgen als:

commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 Auteur: Alexander   Orlov Datum: do 12 mei 23:44:27 2011   0200

replaced deprecated GWT class
- gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script

commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302 Auteur: Alexander   Orlov Datum: do 12 mei 22:10:22 2011   0200

3. Gebruik nu de commit id bfe68bd117e1091c96d2976c99b3bcc8310bebe7:

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

Aangezien de commit-id verwijst naar de commit waar het bestand al was verwijderd, moet u verwijzen naar de commit vlak voor bfe68b, wat u kunt doen door te plakken ^1. Dit betekent: geef me de commit vlak voor bfe68b.


20
2018-03-01 10:48



git checkout /path/to/deleted.file

13
2018-06-25 19:40