Preciso recuperar dois branches do Git que, de alguma forma, excluí durante um push.
Esses dois branches foram criados em um sistema diferente e então enviados para o meu repositório "compartilhado" (github).
No meu sistema, eu (aparentemente) recuperei os ramos durante uma busca:
~/myfolder> git fetch
remote: Counting objects: 105, done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 62 (delta 29), reused 0 (delta 0)
Unpacking objects: 100% (62/62), done.
From github.com:mygiturl
* [new branch] contact_page -> origin/contact_page
731d1bb..e8b68cc homepage -> origin/homepage
* [new branch] new_pictures -> origin/new_pictures
Logo depois disso, fiz um push para enviar minhas alterações locais ao repositório central. Por algum motivo, esses branches foram excluídos do meu sistema local e do repositório central:
~/myfolder> git push
Counting objects: 71, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (43/43), done.
Writing objects: 100% (49/49), 4.99 KiB, done.
Total 49 (delta 33), reused 0 (delta 0)
To [email protected]:mygiturl.git
- [deleted] contact_page
+ e8b68cc...731d1bb homepage -> homepage (forced update)
bb7e9f2..e0d061c master -> master
- [deleted] new_pictures
e38ac2e..bb7e9f2 origin/HEAD -> origin/HEAD
731d1bb..e8b68cc origin/homepage -> origin/homepage
e38ac2e..bb7e9f2 origin/master -> origin/master
* [new branch] origin/contact_page -> origin/contact_page
* [new branch] origin/new_pictures -> origin/new_pictures
Não é muito fácil tirar os galhos da máquina do local de nascimento, então, gostaria de tentar recuperá-los do meu local, se possível.
Todas as informações de "desfazer" do git que pesquisei no Google têm a ver com a recuperação de commits perdidos. Não acho que isso se aplique aqui, já que não tenho UIDs de commit para esses branches.
Gostaria de saber como posso recuperá-los. Também gostaria de saber como eles foram excluídos em primeiro lugar e como posso evitar isso no futuro.
EDIT: por solicitação, aqui está minha configuração de repo
user.name=Craig Walker
[email protected]
alias.unadd=reset HEAD
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
[email protected]:MyGitURL.git
remote.origin.mirror=true
branch.master.remote=origin
branch.master.merge=refs/heads/master
alias.undo=reset --hard
alias.test=push -f ci HEAD:master
alias.st=status
alias.ci=commit
alias.br=branch
alias.co=checkout
alias.ch=checkout
alias.df=diff
alias.lg=log -p
alias.who=shortlog -s --
remote.ci.url=ContinuousIntegrationGitURL
remote.ci.fetch=+refs/heads/*:refs/remotes/ci/*
branch.photo.remote=origin
branch.photo.merge=refs/heads/photos
remote.foo.url=FooGitURL
remote.foo.fetch=+refs/heads/*:refs/remotes/cynthia/*
branch.homepage.remote=origin
branch.homepage.merge=refs/heads/homepage
git config -l
mostra para o repositório local?remote.origin.fetch
refspec não é apropriado para uso comremote.origin.mirror = true
. Você deseja espelhar ou usar o repositório GitHub como um controle remoto normal? Minha resposta deve ter os comandos de que você precisa de qualquer maneira.Respostas:
Não sou especialista. Mas você pode tentar
para encontrar o commit HEAD do branch excluído e recuperá-lo.
fonte
git branch <uid>
recebi de volta. Obrigado!remotes.origin.mirror
eremotes.origin.fetch
, caso contrário, você terá que enfrentar o problema novamente (ou destruir involuntariamente os commits enviados de outros repositórios).git fsck --full --no-reflogs | cut -d' ' -f3 | xargs -P8 git log --oneline | grep 'Release 2.60.0.157'
apenas dois comandos salvam minha vida
1. Isso irá listar todos os HEADs anteriores
2. Isso reverterá o HEAD para o commit que você deletou.
fonte
git reflog
. Posso tentar mais alguma coisa?Seus branches excluídos não são perdidos, eles foram copiados para origin / contact_page e origin / new_pictures "branches de rastreamento remoto" pela busca que você mostrou (eles também foram empurrados para fora pelo push que você mostrou, mas foram colocados em refs / remotes / origin / em vez de refs / heads /). Verifique
git log origin/contact_page
egit log origin/new_pictures
para ver se suas cópias locais são “até à data” com o que você acha que deveria estar lá. Se quaisquer novos commits foram enviados para esses branches (de algum outro repo) entre o fetch e o push que você mostrou, você pode ter "perdido" aqueles (mas provavelmente você poderia encontrá-los no outro repo que mais recentemente fez push desses branches) .Fetch / Push Conflict
Parece que você está buscando em um 'modo remoto' normal (refs / heads remotos / são armazenados localmente em refs / remotes / origin /), mas pressionando em 'modo espelho' (refs locais / são colocados em refs / remotos) . Verifique seu .git / config e reconcilie as configurações
remote.origin.fetch
eremote.origin.push
.Faça um backup
Antes de tentar qualquer mudança, faça um arquivo tar ou zip simples ou seu repositório local inteiro. Dessa forma, se você não gostar do que acontece, pode tentar novamente a partir de um repositório restaurado.
Opção A: reconfigurar como um espelho
Se você pretende usar seu repo remoto como um espelho do seu local, faça o seguinte:
Você também pode eventualmente querer excluir todos os seus refs / remotes / origin / refs, uma vez que eles não são úteis se você estiver operando no modo espelho (seus branches normais tomam o lugar dos branches remotos usuais).
Opção B: reconfigurar como um controle remoto normal
Mas, como parece que você está usando este repositório remoto com vários repositórios de “trabalho”, você provavelmente não deseja usar o modo espelho. Você pode tentar isto:
Então, você acabará por querer excluir as refs falsos / controles remotos / refs origem na sua repo remoto:
git push origin :refs/remotes/origin/contact_page :refs/remotes/origin/new_pictures …
.Push de teste
Tente
git push --dry-run
ver o que elegit push
faria sem que ele fizesse nenhuma alteração no repositório remoto. Se você não gostar do que ele diz que vai fazer, recupere de seu backup (tar / zip) e tente a outra opção.fonte
.git
diretório, certifique-se de verificar.git/packed_refs
além de.git/refs/
.git show-ref
irá despejar todos os seus refs locais (embalados ou 'soltos'). Você ainda deve conseguir encontrar os refs no repo que os enviou originalmente para seu repo do GitHub (em uma máquina diferente? O repo de outra pessoa?). Falhando isso, contanto que você não tenha feito um gc ou ameixa seca, você deve ser capaz dagit fsck
saída para examinar os commits pendentes e anexá-los:git branch contact_page-recovered <SHA-1-of-dangling-commit>
.Se a exclusão for recente o suficiente (como um momento Oh-NÃO!), Você ainda deve ter uma mensagem:
Deleted branch <branch name> (was abcdefghi).
você ainda pode executar:
git checkout abcdefghi
git checkout -b <some new branch name or the old one>
fonte
descobrir o id coimmit
git reflog
recuperar filial local que você excluiu por engano
git branch need-recover-branch-name commitId
push need-recover-branch-name novamente se você excluiu branch remoto também antes
git push origin need-recover-branch-name
fonte
git reflog
, ao invés de ter que adivinhar egit show
.Os dados ainda existem no github, você pode criar um novo branch a partir dos dados antigos:
fonte
Eu acho que você tem uma configuração incompatível para 'fetch' e 'push', então isso fez com que a busca / push padrão não fosse de ida e volta corretamente. Felizmente, você buscou os branches que excluiu subsequentemente, então deve ser capaz de recriá-los com um push explícito.
fonte
git push origin origin/contact_page:contact_page
receber isto:error: src refspec origin/contact_page does not match any
git rev-parse refs/remotes/origin/origin/contact_page
dizer? Por causa da configuração falsa de 'espelho', o branch pode agora ser referenciado aqui no repositório local.Se sua organização usa JIRA ou outro sistema semelhante que está vinculado ao git, você pode encontrar os commits listados no próprio tíquete e clicar nos links para as alterações de código. O Github exclui o branch, mas ainda tem os commits disponíveis para seleção seletiva.
fonte
Pode parecer muito cauteloso, mas freqüentemente copio uma cópia de tudo em que estou trabalhando antes de fazer alterações no controle de origem. Em um projeto Gitlab no qual estou trabalhando, recentemente excluí por engano um branch remoto que queria manter após mesclar uma solicitação de mesclagem. Acontece que tudo que eu tive que fazer para recuperá-lo com o histórico de commits foi enviar novamente. A solicitação de mesclagem ainda era rastreada pelo Gitlab, então ainda mostra o rótulo azul 'mesclado' à direita do branch. Ainda fechei minha pasta local para o caso de algo ruim acontecer.
fonte