Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як stash влаштований усередині і як відновити випадково видалений запис stash?

Запис stash - це звичайні коміти, на які вказує ref refs/stash, а список stash@{n} - це reflog цього ref-а.

Структура одного запису:

      .----W    ← робочий каталог (сам запис stash@{0})
     /    /|
    H----I |    H - HEAD на момент stash, I - стан індексу
           U    U - невідстежувані файли (лише з -u чи -a)
  • W - merge-коміт з батьками H, I і, якщо був -u, - U;
  • окремий коміт для індексу дозволяє git stash apply --index відновити, що саме було в індексі.
git cat-file -p stash@{0}
# tree ...
# parent 84ba035...   ← H
# parent 48c2a34...   ← I
# parent 84d625d...   ← U (untracked files on main)
git show stash@{0}^3   # невідстежувані файли зі stash

Що з цього випливає:

  • git stash drop і успішний pop видаляють лише запис у reflog refs/stash. Самі коміти лишаються в базі об'єктів, доки їх не прибере git gc;
  • до stash можна звертатися як до будь-якого коміту: git diff stash@{0}^1 stash@{0}, git restore --source=stash@{0} -- file.php.

Відновлення видаленого stash:

Якщо щойно виконали pop чи drop, Git друкує хеш:

Dropped refs/stash@{0} (5c3e8a7f...)
git stash apply 5c3e8a7f

Якщо хеш загублено - шукати недосяжні коміти-сироти:

git fsck --no-reflog --unreachable | awk '/commit/ {print $3}' \
  | xargs git log --no-walk --merges --format='%h %ci %s' | grep 'WIP on\|On '

Коміти stash - merge-коміти з повідомленнями «WIP on main» чи «On main: опис». Знайдений хеш - git stash apply <хеш> чи git branch rescue <хеш>.

Обмеження: після git gc (Git запускає його й автоматично) недосяжні об'єкти старші за gc.pruneExpire (за замовчуванням 2 тижні) видаляються остаточно.

git stash branch name stash@{1} - корисний для старих записів: створює гілку від коміту H, застосовує stash і видаляє запис, тож конфліктів з новим кодом не буде.

Докладніше в документації: git stash: обговорення

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання