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

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

14 ответов


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


большую часть времени недоступен фиксации в reflog. Итак,первым делом попробуйте посмотреть на reflog С помощью команды git reflog (который показывает reflog для HEAD).

возможно, что-то проще, если фиксация была частью определенной ветви, все еще существующей, использовать команду git reflog name-of-my-branch. Он также работает с пультом дистанционного управления,например, если вы принудительно нажимаете.


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

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

Если вы хотите использовать GUI, вы можете выполнить всю операцию с gitk.

gitk --reflog

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


верхнее проголосованное решение делает на самом деле больше, чем требуется:

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

или

git checkout -b <branch> <sha>

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

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

git branch <branch> <sha>

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

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

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

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

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


добавлять к tfe ответ: там git-resurrect.sh скрипт contrib/ область источников Git (в git.git repository), который может вам помочь.

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


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

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

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

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

Я бы попробовал git-ressurect.sh скрипт, упомянутый в Якуб!-Хотя -10--> первый.


я использовал следующие команды для поиска и извлечения удаленной ветви. Первые шаги - из описания 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 (GIT-SHA) на основе комментариев фиксации и используйте его в команде ниже. Проверка новой ветви под названием NEW-BRANCH с ранее найденным GIT-SHA:

$ git checkout -b NEW-BRANCH GIT-SHA

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

git branch -d [branch]

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

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

git branch -D [branch]

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

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


на GitHub пользователи Git не установлен:

если вы хотите восстановить его с GitHub сайт, вы можете Hack их сайт ;)

* прежде всего, найдите эти SHAs (commit hashes):

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

... или для частных РЕПО:

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

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

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

• перейдите в раздел ветви и удалите его.

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

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

• добавьте в конец скопированной строки кода следующее:-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-хэш и BranchName с желаемым именем (кстати, это отличный хак, чтобы переименовать ветку из интернета). Если вы не были слишком медленными, вам все равно нужно сделать этот запрос. Например, просто скопируйте-вставьте в терминал.

П. С.

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

обновление

Ахаха, я так взволнован тем фактом, что кто-то во Всемирной паутине нашел мой ответ и на самом деле, прочитав его, нашел его смешным или полезным и поддержал мой умопомрачительный, безумный и неправильный ответ:) это замечательный мир вокруг, и мы, программисты и кодеры, являемся одной из самых сумасшедших частей он


Я перебазировал ветку с remote, чтобы попытаться очистить несколько коммитов, которые я не хотел, и собирался cherrypick правильные, которые я хотел. Конечно, я написал ШАС неправильно...

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

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

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

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

cat lost | cut -d\  -f3 > commits

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

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

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

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


для восстановления удаленных филиала, сначала пройдемся по истории reflog,

git reflog -n 60

где n относится к последним N коммитам. Затем найдите подходящую голову и создайте ветку с этой головой.

git branch testbranch HEAD@{30}

сначала перейдите в Git batch переход к вашему проекту, например:

cd android studio project
cd Myproject
then type :
git reflog

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


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

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


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

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

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

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

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

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