Если я бегу git branch -d XYZ
, есть ли способ восстановить ветку? Есть ли способ вернуться, как будто я не запускал команду удаления ветки?
Если я бегу git branch -d XYZ
, есть ли способ восстановить ветку? Есть ли способ вернуться, как будто я не запускал команду удаления ветки?
Ответы:
Да, вы должны быть в состоянии сделать git reflog
и найти SHA1 для коммита в конце вашей удаленной ветви, а затем просто git checkout [sha]
. И как только вы получите этот коммит, вы можете просто git checkout -b [branchname]
восстановить ветку оттуда.
Благодарим @Cascabel за эту сокращенную / однострочную версию.
Вы можете сделать это за один шаг:
git checkout -b <branch> <sha>
git checkout -b <branch> <sha>
.
<sha>
. Например, как упомянуто выше -git checkout -b <branch> <sha>
CMD+K
)
git reflog --no-abbrev
чтобы увидеть полный <sha>
текст, сокращенный по умолчанию.
git checkout remotes/origin/deleted_branch
.
Большую часть времени недоступные коммиты находятся в reflog. Итак, первое, что нужно попробовать - посмотреть на reflog с помощью команды git reflog
(для которой отображается 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...
Аналогичная команда для легкого восстановления удаленных удаленных файлов: https://stackoverflow.com/a/58853981/717372
Если вам нравится использовать графический интерфейс, вы можете выполнить всю операцию с помощью gitk.
gitk --reflog
Это позволит вам увидеть историю коммитов ветки, как если бы ветка не была удалена. Теперь просто щелкните правой кнопкой мыши самый последний коммит в ветке и выберите пункт меню Create new branch
.
Решение с наибольшим количеством голосов на самом деле делает больше, чем просили:
git checkout <sha>
git checkout -b <branch>
или
git checkout -b <branch> <sha>
перенести вас в новую ветку вместе со всеми последними изменениями, которые вы, возможно, забыли зафиксировать. Это не может быть вашим намерением, особенно в «режиме паники» после потери ветки.
Более чистое (и более простое) решение кажется однострочным (после того, как вы нашли <sha>
с git reflog
):
git branch <branch> <sha>
Теперь ни ваша текущая ветка, ни незафиксированные изменения не затронуты. Вместо этого будет создана только новая ветка вплоть до <sha>
.
Если это не совет, он все равно будет работать, и вы получите более короткую ветвь, тогда вы можете повторить попытку с новым <sha>
и новым именем ветки, пока не получите это правильно.
Наконец, вы можете переименовать успешно восстановленную ветку в то, что она была названа или что-то еще:
git branch -m <restored branch> <final branch>
Само собой разумеется, ключ к успеху был в том, чтобы найти правильный коммит <sha>
, поэтому называйте свои коммиты с умом :)
Добавление к т.ут ответ : есть также git-resurrect.sh сценарий в contrib/
области источников Git (в git.git хранилища), который может помочь вам.
git-resurrect <name>
пытается найти следы названного кончика ветви<name>
и пытается воскресить его. В настоящее время в reflog выполняется поиск сообщений извлечения, а-r
также сообщений слияния. С помощью-m
и-t
, история всех ссылок сканируется дляMerge <name> into other
/Merge <other> into <name>
(соответственно) фиксации тем, что довольно медленно, но позволяет вам воскрешать ветки тем других людей.
Я использовал следующие команды, чтобы найти и получить мою удаленную ветку. Первые шаги взяты из описания 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 id (GIT-SHA) на основе комментариев коммита и используйте его в приведенной ниже команде. Оформить заказ на новую ветку под названием NEW-BRANCH с ранее найденным GIT-SHA:
$ git checkout -b NEW-BRANCH GIT-SHA
Если у вас нет рефлога, например. поскольку вы работаете в пустом хранилище, в котором не включен рефлог, а коммит, который вы хотите восстановить, был создан недавно, другой вариант - найти недавно созданные объекты коммитов и просмотреть их.
Внутри .git/objects
каталога запустите:
find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit
Он находит все объекты (коммиты, файлы, теги и т. Д.), Созданные за последние 12 часов, и фильтрует их, показывая только коммиты. Проверка это тогда быстрый процесс.
Сначала я бы попробовал скрипт git-ressurect.sh, упомянутый в ответе Якуба .
man find
: "-ctime n - статус файла был последний раз изменен n * 24 часа назад." Таким образом, мы должны также изменить 12 на 0,5, чтобы иметь ожидаемое поведение последних 12 часов.
Для пользователей 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)
следующий
• Перейдите в разделы и удалите этот.
• На той же странице, без перезагрузки , откройте DevTools, панель «Сеть». Теперь приготовьтесь ...
• Нажмите восстановить. Вы заметите новую «линию». Щелкните правой кнопкой мыши на нем и выберите «Копировать как cURL» и сохраните этот текст в каком-то редакторе.
• Append до конца скопированной строки кода, это: -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
Заключительный этап
PS
Я понимаю, что это может быть не самое простое или правильное решение, но оно предлагается на случай, если кто-то посчитает его полезным.
git reflog
пример является одним из немногих, на которые нельзя положиться, и поэтому он был полезен, например, при удалении удаленной ветви и потере доступа к компьютеру, что было сделано из ничего полезного reflog
. Обратите внимание , при использовании OAuth или двухфакторной аутентификации на Githubcurl
команды становится вид: curl -u username:token https://api.github.com/user
илиcurl -H "Authorization: token TOKEN" https://api.github.com/repos/USER_OR_ORG_NAME/REPO_NAME/events
Насколько я понимаю, если ветка, которую нужно удалить, может быть достигнута другой веткой, вы можете безопасно удалить ее, используя
git branch -d [branch]
и ваша работа не потеряна. Помните, что ветвь - это не снимок, а указатель на него. Поэтому, когда вы удаляете ветку, вы удаляете указатель.
Вы даже не потеряете работу, если удалите ветку, которая не может быть достигнута другой. Конечно, это будет не так просто, как проверить хеш коммита, но вы все равно можете это сделать. Вот почему Git не может удалить ветку, которая не может быть достигнута с помощью -d
. Вместо этого вы должны использовать
git branch -D [branch]
Это часть обязательного просмотра видео от Скотта Чакона о Git. Проверьте минуты 58:00, когда он говорит о ветках и как их удалить.
reflog
, просто излишни.
Убедитесь, что все это выполняется локально, и подтвердите, что репо находится в желаемом состоянии, прежде чем отправлять в Bitbucket Cloud. Также может быть хорошей идеей клонировать текущее хранилище и сначала протестировать эти решения.
Deleted branch <your-branch> (was <sha>)
2. Для восстановления ветки используйте:
git checkout -b <branch> <sha>
Если вы не знаете «ша» на макушке головы, вы можете:
git reflog
git checkout -b <branch> <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
2.Вы можете затем отобразить каждый коммит, используя один из них:
git log -p <commit>
git cat-file -p <commit>
Я перебросил ветку с пульта, чтобы попытаться очистить несколько коммитов, которые мне не нужны, и собирался выбрать нужные мне. Конечно я написал 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
Это покажет вам diff и передаст информацию для каждого из них. И жду, когда ты нажмешь Enter. Теперь запишите все те, которые вы хотите, и затем выберите их. После того, как вы закончите, просто нажмите Ctrl-C.
БОЛЬШОЕ ДА
если вы используете GIT, выполните следующие простые действия: https://confluence.atlassian.com/bbkb/how-to-restore-a-deleted-branch-765757540.html
если вы используете smartgit и уже переместили эту ветку в исходное положение , найдите эту ветку и щелкните правой кнопкой мыши, затем оформите заказ
Сначала зайдите в git batch the move в ваш проект, например:
cd android studio project
cd Myproject
then type :
git reflog
У всех вас есть список изменений и ссылочный номер взять номер ссылки, а затем
оформить заказ в Android Studio или Git Betcha. другое решение взять номер ссылки и перейти к Android Studio. Нажмите на ветки git вниз, затем нажмите на тег оформления заказа или ревизию после ссылочного номера, и тогда у вас есть ветви.
В дополнение к ответу tfe, вы можете восстановить этот процесс, если он не является сборщиком мусора. Ветвь Git - это просто указатель на определенный коммит в дереве коммитов. Но если вы удалите указатель и коммиты в этой ветке не будут объединены с другой существующей веткой, то git будет обрабатывать их как висячие коммиты и удаляет их во время сборки мусора, который он может периодически запускать автоматически.
Если ваша ветвь не была объединена с существующей веткой, и если она была собрана сборщиком мусора, вы потеряете все коммиты вплоть до точки, откуда ветка была разветвлена из существующей ветки.
Связанная проблема: я пришел на эту страницу после поиска «как узнать, что такое удаленные ветки».
При удалении многих старых веток я почувствовал, что по ошибке удалил одну из новых веток, но не знал названия для ее восстановления.
Чтобы узнать, какие ветви недавно были удалены, выполните следующие действия:
Если вы перейдете на свой Git URL, который будет выглядеть примерно так:
https://your-website-name/orgs/your-org-name/dashboard
Затем вы можете увидеть канал, который удален, кем, в недавнем прошлом.
Я сделал это на компьютере, который я удаляю ветку:
git reflog
ответ:
74b2383 (develope) HEAD@{1}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: checkout: moving from develope to master
74b2383 (develope) HEAD@{3}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{4}: reset: moving to HEAD
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git
и я получаю ветку с этой командой:
git checkout -b newBranchName 74b2383
Просто использование git reflog
не вернуло sha
для меня. Только commit id
(это 8 символов в длину и ша намного)
Так что я использовал
git reflog --no-abbrev
И затем сделайте то же самое, что упомянуто выше:
git checkout -b <branch> <sha>
Обратите внимание, что git branch delete удаляет только локальную копию, а не копию на сервере. Во-первых, на панели Git (значок git на левой панели инструментов), просмотрите ветки и посмотрите, есть ли там ваша ветка в "origin / your_branch_name". Если это так, просто выберите это, и вы должны получить свой код обратно (предложить немедленно скопировать / вставить / сохранить его локально в другом месте).
Если вы не видите «origin / your_branch_name», установите расширение GitLens. Это позволяет визуально просматривать репозитории сервера и находить копию, которую вы синхронизировали с сервером. Если у вас есть несколько репозиториев, обратите внимание, что может потребоваться открыть хотя бы один файл из нужного репозитория, чтобы репозиторий появился в GitLens. Затем:
Откройте панель GitLens
Разверните хранилище
Вы должны увидеть список категорий: Филиалы / Авторы / Remotes / Stashes / etc
Вы должны найти YourLostTreasure в разделе «Филиалы» или, возможно, в разделе «Remotes -> Origins». Надеюсь, вы увидите ветку с нужным именем - если вы развернете ее, вы должны увидеть файлы, которые вы изменили в этой ветке. Дважды щелкните имена файлов, чтобы открыть их, и немедленно сделайте резервную копию этого кода.
Если вы не сразу видите потерянную ветку, покопайтесь и, если найдете что-то многообещающее, немедленно откройте ее и возьмите код. Мне пришлось немного поковыряться, пока я не нашел TheGoldenBranch, и даже тогда в коде отсутствовали последние один или два сохранения (возможно, из-за того, что я не смог выполнить синхронизацию с сервером перед попыткой слияния ветвлений, но случайно щелкнуть) Отделение-Delete). Мой поиск был излишне удлинен, потому что, когда я впервые нашел ветвь, я не был полностью уверен, что имя было правильным, поэтому продолжал искать, и потребовалось некоторое время, чтобы повторно найти эту первую ветку. (Таким образом, Carpe Carpum, а затем продолжать искать.)