Можно ли восстановить ветвь после ее удаления в Git?

Если я запустил git branch -d XYZ, есть ли способ восстановить ветвь? Есть ли способ вернуться, как будто я не запускал команду удаления ветки?

Ответ 1

Да, вы должны быть в состоянии сделать git reflog и найти SHA1 для коммита в конце вашей удаленной ветки, а затем просто git checkout [sha]. И как только вы получите этот коммит, вы можете просто сделать git checkout -b [branchname] чтобы воссоздать ветку оттуда.


Благодарим @Cascabel за эту сокращенную/однострочную версию.

Вы можете сделать это за один шаг:

git checkout -b <branch> <sha>

Ответ 2

Большую часть времени недоступные коммиты находятся в reflog. Итак, первое, что нужно попробовать, - посмотреть журнал reflog с помощью команды git reflog (которая отображает журнал ссылок для HEAD).

Возможно, что-то проще, если коммит был частью определенной ветки, которая еще существует, - это использовать команду git reflog name-of-my-branch. Он также работает с пультом дистанционного управления, например, если вы принудительно нажали (дополнительный совет: всегда вместо этого предпочитайте git push --force-with-lease, что лучше предотвращает ошибки и более исправимо).


Если ваши коммиты отсутствуют в вашем reflog (возможно, из-за того, что они были удалены сторонним инструментом, который не записывает в reflog), я успешно восстановил ветку, сбросив свою ветку до шага коммита, найденного с помощью такой команды, как что (он создает файл со всеми висячими коммитами):

git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt

Если вы должны использовать его более одного раза (или хотите сохранить его где-нибудь), вы также можете создать псевдоним с помощью этой команды...

git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'

и используйте его с git rescue

Чтобы исследовать найденные коммиты, вы можете отобразить каждый коммит, используя несколько команд для их просмотра.

Чтобы отобразить метаданные фиксации (автор, дата создания и сообщение коммита):

git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

Чтобы увидеть также различия:

git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

Как только вы нашли свой коммит, создайте ветку для этого коммита с помощью:

git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560

Для тех, которые находятся под Windows и им нравятся графические интерфейсы, вы можете легко восстановить коммиты (а также некоммитированные промежуточные файлы) с помощью GitExtensions, используя функцию Repository => Git maintenance => Recover lost objects...

Ответ 3

Если вы хотите использовать графический интерфейс, вы можете выполнить всю операцию с помощью gitk.

gitk --reflog

Это позволит вам увидеть историю фиксации ветки, как если бы ветка не была удалена. Теперь просто щелкните правой кнопкой мыши самую последнюю фиксацию на ветку и выберите пункт меню Create new branch.

Ответ 4

Самое популярное решение действительно больше, чем было запрошено:

git checkout <sha>
git checkout -b <branch>

или

git checkout -b <branch> <sha>

переместит вас в новую ветку вместе со всеми недавними изменениями, которые вы, возможно, забыли совершить. Это может быть не ваше намерение, особенно когда в "режиме паники" после потери ветки.

A более чистое (и более простое) решение кажется однострочным (после того, как вы нашли <sha> с git reflog):

git branch <branch> <sha>

Теперь ни ваша текущая ветвь, ни неизменные изменения не затронуты. Вместо этого только новая ветвь будет создана до <sha>.

Если это не подсказка, она все равно будет работать, и вы получите более короткую ветку, после чего вы сможете повторить попытку с новым <sha> и новым именем ветки, пока не получите правильное решение.

Наконец, вы можете переименовать успешно восстановленную ветку в то, что она была названа, или что-то еще:

git branch -m <restored branch> <final branch>

Излишне говорить, что ключом к успеху было найти правильную фиксацию <sha>, поэтому назовите свои коммиты разумно:)

Ответ 5

Добавление в tfe ответ: есть также git-resurrect.sh script в области contrib/ в Git источники (в хранилище git.git), которые могут вам помочь.

git-resurrect <name> пытается найти следы кончика ответвления называется <name> и пытается его воскресить. В настоящее время reflog поиск сообщений проверки, а с помощью -r - также слияние сообщений. С -m и -t, история всех refs сканируется для Merge <name> into other/Merge <other> into <name> (соответственно) объектов фиксации, которые довольно медленный, но позволяет воскрешать тему других людей ветки.

Ответ 6

Если у вас нет reflog, например. потому что вы работаете в голом репозитории, в котором нет reflog, и коммит, который вы хотите восстановить, был создан недавно, другой вариант - найти недавно созданные объекты фиксации и просмотреть их.

Изнутри каталога .git/objects выполните:

find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit

Это находит все объекты (фиксации, файлы, теги и т.д.), созданные за последние 12 часов, и фильтрует их для отображения только коммитов. Проверка их - это быстрый процесс.

Я попробовал бы git -ressurect.sh script, упомянутый в ответ Jakub, хотя.

Ответ 7

Для пользователей GitHub без установленного Git:

Если вы хотите восстановить его с веб-сайта GitHub, вы можете использовать их API, чтобы получить список событий, связанных с репо:

Первый

  • найти эти SHA (зафиксировать хэши):

    curl -i https://api.github.com/repos/PublicUser/PublicRepo/events

    ... или для частных репозиториев:

    curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events

    (будет предложено ввести пароль GitHub)

    • (Если для репо требуется двухфакторная аутентификация, см. Комментарии к этому ответу ниже.)

следующий

  • перейдите на GitHub и создайте новую временную ветку, которая будет удалена навсегда (предпочтительно Chrome).

• Перейдите в разделы и удалите этот.

На той же странице, без перезагрузки, откройте DevTools, панель "Сеть". Теперь готовимся...

• Нажмите восстановить. Вы заметите новую "линию". Щелкните правой кнопкой мыши на нем и выберите "Копировать как cURL" и сохраните этот текст в каком-то редакторе.

• Добавить в конец скопированной строки кода этот: -H "Cookie=".

Теперь вы должны получить что-то вроде:

    curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed

Заключительный этап

  • замените "BranchSHA" на ваш пепел SHA -H и BranchName на нужное имя (кстати, это отличный способ переименовать ветку из сети). Если вы не слишком медлительны, вам все равно нужно сделать этот запрос. Например, просто скопируйте и вставьте в терминал.

PS

Я понимаю, что это может быть не самое простое или правильное решение, но оно предлагается на случай, если кто-то посчитает его полезным.

Ответ 8

Из моего понимания, если удаляемая ветка может быть достигнута другой веткой, вы можете безопасно ее удалить, используя

git branch -d [branch]

и ваша работа не потеряна. Помните, что ветка - это не снимок, а указатель на один. Поэтому, когда вы удаляете ветвь, вы удаляете указатель.

Вы даже не потеряете работу, если вы удалите ветку, недоступную другой. Конечно, это будет не так просто, как проверить хеш-код фиксации, но вы все равно можете это сделать. Поэтому Git не может удалить ветвь, которая не может быть достигнута с помощью -d. Вместо этого вы должны использовать

git branch -d [branch]

Это часть обязательного просмотра видео от Скотта Чакона о Git. Проверьте минутку 58:00, когда он расскажет о ветких и как их удалить.

Введение в Git со Скоттом Чаконом из GitHub

Ответ 9

Я использовал следующие команды для поиска и извлечения удаленной ветки. Первые шаги из описания gcb.

$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\  -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline

Теперь найдите идентификатор git commit (GIT -SHA) на основе комментариев коммита и используйте его в приведенной ниже команде. Оформить покупку нового ветки под названием NEW-BRANCH с ранее найденным GIT -SHA:

$ git checkout -b NEW-BRANCH GIT-SHA

Ответ 10

Я переустановил ветку с удаленного, чтобы попытаться очистить несколько коммитов, которых я не хотел, и собирался сделать черри нужные, которые я хотел. Конечно, я написал SHA неправильно...

Вот как я их нашел (в основном, более простой интерфейс/взаимодействие от вещей по ответам здесь):

Сначала создайте список свободных коммитов в вашем журнале. Сделайте это как можно скорее и перестаньте работать, так как они могут быть сброшены сборщиком мусора.

git fsck --full --no-reflogs --unreachable --lost-found > lost

Создает файл lost со всеми коммитами, на которые вам придется посмотреть. Чтобы упростить нашу жизнь, разрежьте только SHA:

cat lost | cut -d\  -f3 > commits

Теперь у вас есть файл commits со всеми коментами, которые вы должны посмотреть.

Предполагая, что вы используете Bash, последний шаг:

for c in `cat commits`; do  git show $c; read; done

Это покажет вам информацию о различиях и фиксации для каждого из них. И ждите, пока вы нажмете Enter. Теперь запишите все те, которые вы хотите, а затем вишни - заберите их. После того, как вы закончите, просто нажмите Ctrl-C.

Ответ 11

Для восстановления удаленной ветки сначала перейдите в историю reflog,

git reflog -n 60

Где n указывает на последние n коммитов. Затем найдите нужную голову и создайте ветку с этой головой.

git branch testbranch [email protected]{30}

Ответ 12

Убедитесь, что все это выполняется локально, и подтвердите, что репо находится в желаемом состоянии, прежде чем отправлять в Bitbucket Cloud. Также может быть хорошей идеей клонировать текущее хранилище и сначала протестировать эти решения.

  1. Если вы только что удалили ветку, вы увидите что-то вроде этого в своем терминале:
    Deleted branch <your-branch> (was <sha>)

2. Для восстановления ветки используйте:

    git checkout -b <branch> <sha>

Если вы не знаете "ша" на макушке головы, вы можете:

  1. Найдите 'sha' для коммита в конце удаленной ветки, используя:
    git reflog
  1. Чтобы восстановить ветку, используйте:
    git checkout -b <branch> <sha>

Если ваши коммиты отсутствуют в вашем журнале:

  1. Вы можете попытаться восстановить ветку, сбросив ветку до шага коммита, найденного с помощью такой команды:
    git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt

2.Вы можете затем отобразить каждый коммит, используя один из них:

    git log -p <commit>
    git cat-file -p <commit>

Ответ 13

БОЛЬШОЕ ДА

если вы используете GIT, выполните следующие простые шаги: https://confluence.atlassian.com/bbkb/how-to-restore-a-deleted-branch-765757540.html

если вы используете smartgit и уже нажимаете эту ветку на начало координат, найдите эту ветку и щелкните правой кнопкой мыши, затем проверьте

Ответ 14

Сначала перейдите в git пакетный переход к вашему проекту, например:

cd android studio project
cd Myproject
then type :
git reflog

У вас есть список изменений, а номер ссылки - номер ref, а затем checkout
из студии android или из git betcha. другое решение возьмем номер ref и перейдите в андроид-студию, нажмите на git ветки вниз, затем нажмите на тег checkout или версию за ссылочным номером, затем lol у вас есть ветки.

Ответ 15

Добавляя к ответу tfe, вы можете восстановиться с указанным процессом, если только он не совершает ошибку, это не сбор мусора. Разделитель Git - это просто указатель на конкретную фиксацию в дереве фиксации. Но если вы удаляете указатель и коммиты на этой ветке не объединяются в другую существующую ветвь, то Git рассматривает ее как зависающую фиксацию и удаляет ее во время сбора мусора, которая может периодически запускаться автоматически.

Если ваша ветка не была объединена с существующей ветвью, и если она была собрана в мусор, то вы потеряете все коммиты до точки, откуда ветвь была разветвлена ​​из существующей ветки.

Ответ 16

Связанная с этим проблема: Я пришел на эту страницу после поиска "как узнать, что такое удаленные ветки".

При удалении многих старых ветвей я почувствовал, что ошибочно удалил одну из новых ветвей, но не знал имя, чтобы восстановить его.

Чтобы узнать, какие ветки удалены недавно, выполните следующие действия:

Если вы перейдете на свой Git URL-адрес, который будет выглядеть примерно так:

https://your-website-name/orgs/your-org-name/dashboard

Затем вы можете увидеть фид, что удалено, кем, в недавнем прошлом.

Ответ 17

Просто использование git reflog не возвращало sha для меня. Только commit id (который длится 8 символов, а ша - длиннее)

Поэтому я использовал git reflog --no-abbrev

И затем сделайте то же самое, что указано выше: git checkout -b <branch> <sha>

Ответ 18

Я сделал это на компьютере, который я удаляю ветку:

git reflog

Ответ:

74b2383 (develope) [email protected]{1}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) [email protected]{2}: checkout: moving from develope to master
74b2383 (develope) [email protected]{3}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) [email protected]{4}: reset: moving to HEAD
40ef328 (HEAD -> master, origin/master, origin/HEAD) [email protected]{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git

и я получаю ветку с помощью этой команды:

git checkout -b newBranchName 74b2383