Atualmente, tenho um repositório Git local, o qual envio por push para um repositório Github.
O repositório local possui ~ 10 confirmações e o repositório Github é uma duplicata sincronizada disso.
O que eu gostaria de fazer é remover TODO o histórico de versões do repositório Git local, para que o conteúdo atual do repositório apareça como o único commit (e, portanto, as versões mais antigas dos arquivos no repositório não são armazenadas).
Eu gostaria de fazer essas alterações no Github.
Eu investiguei a rebase do Git, mas isso parece ser mais adequado para remover versões específicas. Outra solução em potencial é excluir o repositório local e criar um novo - embora isso provavelmente crie muito trabalho!
ETA: Existem diretórios / arquivos específicos que não são rastreados - se possível, eu gostaria de manter o rastreamento desses arquivos.
fonte
Respostas:
Aqui está a abordagem da força bruta. Também remove a configuração do repositório.
Nota : Isso NÃO funciona se o repositório tiver submódulos! Se você estiver usando submódulos, deverá usar, por exemplo, rebase interativa
Etapa 1: remover todo o histórico ( verifique se você tem backup, isso não pode ser revertido )
Etapa 2: reconstruir o repositório Git apenas com o conteúdo atual
Etapa 3: pressione o GitHub.
fonte
.gitignore
deve lidar com isso, certo?git commit -m "Initial commit"
, provavelmente poderá pular agit remote add ...
parte, assumindo que já estava na sua configuração, e seguir em frente pressionando. Funcionou para mim.A única solução que funciona para mim (e mantém os submódulos funcionando) é
A exclusão
.git/
sempre causa problemas enormes quando tenho submódulos. O uso degit rebase --root
alguma forma causaria conflitos para mim (e levaria muito tempo, pois eu tinha muita história).fonte
git push -f origin master
como a última operação e o sol brilhará novamente em seu novo repositório! :)git gc --aggressive --prune all
todo o ponto de perder a história seria desperdiçada.Esta é a minha abordagem preferida:
Isso criará um novo ramo com um commit que adiciona tudo no HEAD. Não altera mais nada, por isso é completamente seguro.
fonte
git-rev-parse
documentos. O que está acontecendo aqui égit-commit-tree
requer uma referência a uma árvore (um instantâneo do repositório), masHEAD
é uma revisão. Para encontrar a árvore associada a uma confirmação, usamos o<rev>^{<type>}
formuláriogit push --force <remote> new_branch_name:<remote-branch>
A outra opção, que pode resultar em muito trabalho, se você tiver muitos commits, é uma rebase interativa (assumindo que sua versão do git seja> = 1.7.12):
git rebase --root -i
Quando apresentado com uma lista de confirmações no seu editor:
Salvar e fechar. O Git começará a ser reformulado.
No final, você teria um novo commit raiz que é uma combinação de todos os que vieram depois dele.
A vantagem é que você não precisa excluir seu repositório e, se tiver dúvidas, sempre terá um substituto.
Se você realmente deseja aprimorar seu histórico, redefina o mestre para esse commit e exclua todos os outros ramos.
fonte
error: failed to push some refs to
git push --force-with-lease
. force-with-lease é usado porque é menos destrutivo que --force.Variante do método proposto por larsmans :
Salve sua lista de arquivos não rastreados:
Salve sua configuração do git:
Em seguida, execute os primeiros passos de larsmans:
Restaure sua configuração:
Rastreie seus arquivos não rastreados:
Em seguida, confirme:
E, finalmente, envie para o seu repositório:
fonte
Abaixo está um script adaptado da resposta de @Zeelot. Ele deve remover o histórico de todas as ramificações, não apenas da ramificação principal:
Funcionou para meus propósitos (não estou usando submódulos).
fonte
git branch
incluirá um asterisco ao lado de sua ramificação com check-out, que será globbed, fazendo com que ela seja resolvida em todos os arquivos ou pastas como se esses também fossem nomes de ramificações. Em vez disso, usei ogit branch --format="%(refname:lstrip=2)"
que me deu apenas os nomes das filiais.git push --force origin master
ougit push --force-with-lease
? Aparentemente, o último é mais seguro (consulte stackoverflow.com/questions/5509543/… ) #Você pode usar clones rasos (git> 1.9):
Leitura adicional: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
fonte
git filter-branch
é a ferramenta de cirurgia principal.--parent-filter
coloca os pais no stdin e deve imprimir os pais reescritos no stdout; O unixtrue
sai com sucesso e imprime nada, então: sem pais.@^!
é uma abreviação do Git para "o chefe compromete, mas nenhum de seus pais". Em seguida, exclua todos os outros árbitros e empurre à vontade.fonte
Basta excluir o repositório do Github e criar um novo. De longe, a abordagem mais rápida, fácil e segura. Afinal, o que você precisa obter ao executar todos esses comandos na solução aceita quando tudo o que você deseja é o ramo principal com uma única confirmação?
fonte
O método abaixo é exatamente reproduzível, portanto, não há necessidade de executar o clone novamente se os dois lados forem consistentes; basta executar o script do outro lado também.
Se você quiser limpá-lo, tente este script:
http://sam.nipl.net/b/git-gc-all-ferocious
Eu escrevi um script que "mata histórico" para cada ramificação no repositório:
http://sam.nipl.net/b/git-kill-history
veja também: http://sam.nipl.net/b/confirm
fonte
git-hash: not found
eSupport for <GIT_DIR>/info/grafts is deprecated
git log HEAD~${1:-0} -n1 --format=%H
, aqui, sam.aiki.info/b/git-hash Seria melhor colocar tudo em um script para consumo público. Se eu usá-lo novamente, posso descobrir como fazê-lo com o novo recurso que substitui "enxertos".Uma resposta mais conceitual:
O git garbage coleta automaticamente commits antigos se nenhuma tag / branches / refs apontar para eles. Então você simplesmente precisa remover todas as tags / branches e criar um novo commit órfão, associado a qualquer branch - por convenção, você deixaria o branch
master
apontar para esse commit.As confirmações antigas e inacessíveis nunca mais serão vistas por ninguém, a menos que elas pesquisem com comandos git de baixo nível. Se isso é suficiente para você, eu apenas pararia por aí e deixaria o GC automático fazer seu trabalho sempre que desejar. Se você quiser se livrar deles imediatamente, pode usar
git gc
(possivelmente com--aggressive --prune=all
). Para o repositório remoto do git, não há como forçar isso, a menos que você tenha acesso ao shell do sistema de arquivos.fonte
Aqui está:
Também hospedado aqui: https://gist.github.com/Zibri/76614988478a076bbe105545a16ee743
fonte
Resolvi um problema semelhante apenas excluindo a
.git
pasta do meu projeto e reintegrando-o com o controle de versão através do IntelliJ. Nota: A.git
pasta está oculta. Você pode vê-lo no terminal comls -a
e, em seguida, removê-lo usandorm -rf .git
.fonte
Para isso, use o comando Shallow Clone git clone - profundidade 1 URL - Clona apenas o HEAD atual do repositório
fonte
Mais informações aqui.
O tutoturial do Git aqui fornece ajuda sobre como limpar o repositório:
fonte