Перейти к основному содержимому

Как восстановить удаленный тайник в Git

· 4 мин. чтения

Задача: Медиана двух отсортированных массивов

Даны два отсортированных массива размерами n и m. Найдите медиану слияния этих двух массивов.
Временная сложность решения должна быть O(log(m + n)) ...

ANDROMEDA

1. Обзор

Такие команды, как git stash и git stash pop , используются для Shelve (stash) и восстановления изменений в нашем рабочем каталоге. В этом руководстве мы узнаем, как восстановить удаленный тайник в Git .

2. Сохранение изменений в рабочем каталоге

Для нашего примера предположим, что мы разветвили и клонировали репозиторий Git . Теперь давайте внесем некоторые изменения в файл README.md , просто добавив новую строку в конец и проверив состояние нашего рабочего каталога:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md

no changes added to commit (use "git add" and/or "git commit -a")

Отсюда мы можем использовать команду git stash , чтобы временно отложить наши изменения.

$ git stash
Saved working directory and index state WIP on master: a8088442db Updated pom.xml

Теперь, если снова сделать git status , мы увидим, что наш рабочий каталог чист.

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

3. Восстановление спрятанных изменений и поиск хеша

Давайте посмотрим, как мы можем восстановить спрятанные изменения и найти хеш, связанный с фиксацией тайника.

3.1. Восстановление спрятанных изменений в рабочем каталоге

Мы можем вернуть спрятанные изменения обратно в наш рабочий каталог следующим образом:

$ git stash pop
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (59861637f7b599d87cb7a1ff003f1b0212e8908e)

Как видно из последней строки, git stash pop не только восстанавливает спрятанные изменения, но и удаляет ссылку на соответствующий коммит.

3.2. Поиск хеша при открытом терминале

Если наш терминал все еще открыт, мы можем легко найти хэш, сгенерированный после выполнения git stash pop . В нашем примере в последней строке отображается хэш 59861637f7b599d87cb7a1ff003f1b0212e8908e.

3.3. Восстановление хэша после закрытия терминала

Даже если мы закрыли терминал, мы все равно можем найти наш хэш следующим образом:

$ git fsck --no-reflog
Checking object directories: 100% (256/256), done.
Checking objects: 100% (302901/302901), done.
dangling commit 59861637f7b599d87cb7a1ff003f1b0212e8908e

Теперь нам виден хэш коммита для выпавшего тайника.

4. Восстановление выпавшего тайника

Обычно нам не нужна запись в тайник после того, как мы ее применили. Однако может возникнуть ситуация, когда мы захотим вернуться к записи в тайнике после того, как мы ее уронили. Например, при использовании git reset –hard HEAD все незафиксированные изменения из нашего рабочего каталога будут удалены. В этой ситуации мы можем захотеть вспомнить некоторые ранее спрятанные изменения, даже если они были удалены.

4.1. Используйте хэш для восстановления тайника

Используя хеш для висячего коммита, мы все еще можем восстановить эти изменения:

$ git stash apply 59861637f7b599d87cb7a1ff003f1b0212e8908e
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.md

no changes added to commit (use "git add" and/or "git commit -a")

Мы видим, что наш рабочий каталог восстановлен с изменениями, которые были спрятаны ранее.

4.2. Поиск всех хеш-коммитов

Если у нас нет хэша, мы можем его найти:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

Здесь мы объединяем нашу опцию –no-reflog с awk , чтобы отфильтровать для нас только хэш.

5. Вывод

В этой статье мы увидели, как работает git stash и как он удаляет запись, когда мы его используем. Затем мы увидели, как можно использовать отброшенную запись, когда мы знаем ее хэш, и как можно найти хеш коммита тайника.