Git: восстановление данных
Что делать, если случайно был удален коммит или ветка? А что делать, если после этого командой разработчиков были внесены изменения, а через некоторое время выяснилось, что удаленные данные могли бы быть полезны?
Здесь я кратко опишу, как можно восстановить удаленные данные.
У меня есть тестовый репозиторий. Вот его история:
* 7a4ff93e291ac18ed49fee06364d01f88390aead (HEAD -> master) 20260225-04
* 49cc776d6bff317e6503491f9edc16df8ee49093 20260225-03
* 18580d5cee272ffed97c7ec9d7468c2bd12bf9f4 20260225-02
* 3f3b3a460598263acd04d152a3414413702b21a0 20260225-01
* 6e394ce02bb38878c84822488a1ec03ed92ad36f C5
* 56bfde7516792f6010f1f9d51ab1f7ba6e801d17 C4
|\
| * 2259d8c02f538082171bb856b4e1514383c7dd27 (testing) T3
| * 0eededebb913f8892ba86b7ac744f74e582d165e T2
| * 8c28ae580ecaca626543b24ba5904552f4d39003 T1
* | 2d5d755d35db194779539c54d78a214d660007a9 C3
* | 1f4710806c431a6d09c77b7d8714845d7a523de9 C2
* | 051a14c93715e4d7f6ff6f8d891bb3d33c20d30a C1
|/
* f5aa9effa280e70dd670720e9b0fa9a5a660e59b C1
Теперь я удаляю все, что было изменено позже коммита C5:
Теперь история репозитория такая:
* 6e394ce02bb38878c84822488a1ec03ed92ad36f (HEAD -> master) C5
* 56bfde7516792f6010f1f9d51ab1f7ba6e801d17 C4
|\
| * 2259d8c02f538082171bb856b4e1514383c7dd27 (testing) T3
| * 0eededebb913f8892ba86b7ac744f74e582d165e T2
| * 8c28ae580ecaca626543b24ba5904552f4d39003 T1
* | 2d5d755d35db194779539c54d78a214d660007a9 C3
* | 1f4710806c431a6d09c77b7d8714845d7a523de9 C2
* | 051a14c93715e4d7f6ff6f8d891bb3d33c20d30a C1
|/
* f5aa9effa280e70dd670720e9b0fa9a5a660e59b C1
Где мне взять удаленные коммиты? Один из вариантов - посмотреть историю изменения указателя HEAD:
6e394ce (HEAD -> master) HEAD@{0}: reset: moving to 6e394ce02bb38878c84822488a1ec03ed92ad36f
7a4ff93 HEAD@{1}: commit: 20260225-04
49cc776 HEAD@{2}: commit: 20260225-03
18580d5 HEAD@{3}: commit: 20260225-02
3f3b3a4 HEAD@{4}: commit: 20260225-01
6e394ce (HEAD -> master) HEAD@{5}: commit: C5
56bfde7 HEAD@{6}: commit (merge): C4
2d5d755 HEAD@{7}: commit: C3
1f47108 HEAD@{8}: checkout: moving from testing to master
2259d8c (testing) HEAD@{9}: commit: T3
0eedede HEAD@{10}: checkout: moving from master to testing
1f47108 HEAD@{11}: commit: C2
051a14c HEAD@{12}: checkout: moving from sast to master
2d4ea58 (sast) HEAD@{13}: commit: SAST2
fd4424d HEAD@{14}: commit: SAST1
0eedede HEAD@{15}: checkout: moving from testing to sast
0eedede HEAD@{16}: checkout: moving from master to testing
051a14c HEAD@{17}: commit: C1
f5aa9ef HEAD@{18}: checkout: moving from testing to master
0eedede HEAD@{19}: commit: T2
8c28ae5 HEAD@{20}: commit: T1
f5aa9ef HEAD@{21}: checkout: moving from master to testing
f5aa9ef HEAD@{22}: commit (initial): C1
Из вывода видно, что после коммита C5 были еще коммиты 7a4ff93, 49cc776, 18580d5 и 3f3b3a4.
Можно создать ветку от последнего (самого свежего) из удаленных коммитов:
Теперь можно вывести историю созданной ветки:
7a4ff93e291ac18ed49fee06364d01f88390aead (recover-branch) 20260225-04
49cc776d6bff317e6503491f9edc16df8ee49093 20260225-03
18580d5cee272ffed97c7ec9d7468c2bd12bf9f4 20260225-02
3f3b3a460598263acd04d152a3414413702b21a0 20260225-01
6e394ce02bb38878c84822488a1ec03ed92ad36f (HEAD -> master) C5
56bfde7516792f6010f1f9d51ab1f7ba6e801d17 C4
2d5d755d35db194779539c54d78a214d660007a9 C3
2259d8c02f538082171bb856b4e1514383c7dd27 (testing) T3
1f4710806c431a6d09c77b7d8714845d7a523de9 C2
051a14c93715e4d7f6ff6f8d891bb3d33c20d30a C1
0eededebb913f8892ba86b7ac744f74e582d165e T2
8c28ae580ecaca626543b24ba5904552f4d39003 T1
f5aa9effa280e70dd670720e9b0fa9a5a660e59b C1
Таким образом данные были восстановлены. Видно, что в этой ветке есть коммиты и файлы из них будут доступны, при переключении в эту ветку.
Может оказаться, что история команд, из которой я узнал хэши удаленых коммитов, также будет удалена или очищена. В этом случае можно запустить проверку целостности репозитория:
В этом случае те коммиты, который не "привязаны" ни к каким другим (висячие) будут выведены в качестве предупреждения. Там будут выведены и их хэши.