Como reverter o commit inicial do git?

358

Eu me comprometo com um repositório git pela primeira vez; Lamento o commit e quero revertê-lo. eu tento

# git reset --hard HEAD~1

Recebo esta mensagem:

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.

Esta confirmação é a primeira confirmação do repositório. Alguma idéia de como desfazer o commit inicial do git?

Chau Chee Yang
fonte

Respostas:

566

Você só precisa excluir o ramo em que está. Você não pode usar, git branch -Dpois isso tem uma verificação de segurança contra isso. Você pode usar update-refpara fazer isso.

git update-ref -d HEAD

Você não usar rm -rf .gitou qualquer coisa como isso como isso irá limpar completamente todo o seu repositório, incluindo todos os outros ramos, bem como o ramo que você está tentando repor.

CB Bailey
fonte
11
Tentei isso enquanto estava em uma rebase - queria dividir o primeiro commit - e git status, para minha surpresa, git disse fatal: Not a git repository (or any parent up to mount point ...)!
Matt Fenwick
11
isso não funcionou para mim. Crie arquivos incluindo alguns que devem ser ignorados, mas não .gitignore. git add ., git commit -m "initial commit", git update-ref -D HEAD, Crie um .gitignore, aviso de que git ainda está vendo os arquivos adicionados anteriormente que deve ignorado. Em outras palavras git update-ref -d HEAD, não me levou de volta ao estado antes do commit inicial.
gman
11
Mas esse é o ponto da pergunta original. Voltando ao estado imediatamente antes do commit inicial.
gman
2
git reset --hard HEAD~1removeria os arquivos adicionados para todas as outras confirmações. Claramente, a questão é como chegar ao mesmo estado em que esse comando funciona em todos os outros casos. Veja esta lista para provar que sua solução não funciona gist.github.com/greggman/522fa69a21d6cfb3ff0b
gman
11
No caso de alguém fica confuso com os comentários de gman: git update-ref -d HEAD se realmente reverter o commit inicial, mas mantém todas as alterações anteriormente cometidos adicionadas ao índice. Se você também deseja remover essas alterações, basta executar uma sequência git reset --hard. Mesmo que incompleta, essa resposta é realmente a melhor, então evite usá-la rm -fr .git(a menos que você saiba o que está fazendo).
rsenna
62

Você pode excluir o HEAD e restaurar seu repositório para um novo estado, onde é possível criar um novo commit inicial:

git update-ref -d HEAD

Depois de criar um novo commit, se você já tiver enviado por push para remoto, será necessário forçá-lo ao remoto para substituir o commit inicial anterior:

git push --force origin
frazras
fonte
11
Vale notar ... este é o comando correto, mas não exclui o HEAD ... exclui a ref (localizada em .git \ refs \ heads) que o arquivo .git \ HEAD fez check-out. Depois de executar este comando, você ainda poderá encontrar o arquivo HEAD apontando para o arquivo refs / heads / <name> que você excluiu, mas se você seguir esse caminho, verá que o cabeçalho ref não existe mais.
DanK 25/07
15

Esta pergunta foi vinculada a este post do blog e uma solução alternativa foi proposta para as versões mais recentes do Git:

git branch -m master old_master
git checkout --orphan master
git branch -D old_master

Esta solução assume que:

  1. Você tem apenas um commit em sua masterfilial
  2. Não existe um ramo chamado, old_masterentão estou livre para usar esse nome

Ele renomeará o ramo existente old_mastere criará um novo ramo órfão master (como é criado para novos repositórios), após o qual você pode excluir livrementeold_master ... ou não. Você decide.

Nota: Mover ou copiar uma ramificação git preserva seu reflog (consulte este código ) ao excluir e, em seguida, criar uma nova ramificação a destrói. Como você deseja voltar ao estado original sem histórico, provavelmente deseja excluir a ramificação, mas outras pessoas podem considerar esta pequena nota.

sem sentido
fonte
11

Nas condições estipuladas na pergunta:

  • A confirmação é a primeira confirmação no repositório.
  • O que significa que houve muito poucos comandos executados:
    • a git init,
    • presumivelmente algumas git addoperações,
    • e uma git commit,
    • e isso é tudo!

Se essas pré-condições forem atendidas, a maneira mais simples de desfazer o commit inicial seria:

rm -fr .git

do diretório em que você fez git init. Você pode refazer o procedimento git initpara recriar o repositório Git e refazer as adições com quaisquer alterações que você se arrepende de não ter feito na primeira vez e refazer o commit inicial.

PERIGO! Isso remove o diretório do repositório Git.

Ele remove o diretório do repositório Git de forma permanente e irrecuperável, a menos que você tenha backups em algum lugar. Sob as pré-condições, você não tem nada que queira manter no repositório, para não perder nada. Todos os arquivos que você adicionou ainda estão disponíveis nos diretórios de trabalho, supondo que você ainda não os modificou e não os excluiu etc. No entanto, fazer isso é seguro apenas se você não tiver mais nada no seu repositório. Sob as circunstâncias descritas na pergunta 'confirmar o repositório pela primeira vez - e depois se arrepender', é seguro. Muitas vezes, porém, não é seguro.

Também é seguro fazer isso para remover um repositório clonado indesejado; não causa danos ao repositório do qual foi clonado. Ele descarta tudo o que você fez em sua cópia, mas não afeta o repositório original.

Tenha cuidado, mas é seguro e eficaz quando as pré-condições são atendidas.

Se você fez outras coisas com seu repositório que deseja preservar, essa não é a técnica apropriada - seu repositório não atende mais às condições prévias para que isso seja apropriado.

Jonathan Leffler
fonte
9
Este é um mau conselho. E se houver outras coisas no repositório que você não queira perder?
Matt Fenwick
5
Então não seria o commit inicial, seria? Há apenas um commit inicial.
Jonathan Leffler
9
"Então não seria o commit inicial" - na verdade, sim. Você está negligenciando o caso muito comum de várias ramificações. Veja a resposta de Charles.
Matt Fenwick
2
Útil, no entanto, deve vir com um aviso.
Simon Bengtsson
5
Isso realmente funciona. A resposta aceita não. Veja o comentário
gman
3

Você não pode. Assim:

rm -rf .git/
git init
git add -A
git commit -m 'Your new commit message'
ma11hew28
fonte
11
Ele tentou dizer git reset --hard, então por que ele faria git add -A?
Aristóteles Pagaltzis
3

Vou jogar o que funcionou para mim no final. Eu precisava remover a confirmação inicial em um repositório, pois os dados em quarentena haviam sido extraviados, a confirmação já havia sido enviada.

Verifique se você está atualmente no ramo direito.

git checkout master

git update-ref -d HEAD

git commit -m "Initial commit

git push -u origin master

Isso foi capaz de resolver o problema.

Importante

Este estava em um repositório interno que não estava acessível ao público; se o seu repositório estava acessível ao público, assuma que qualquer coisa que você precise reverter já foi puxada por outra pessoa.

Edward
fonte
1

Eu me pergunto por que "corrigir" não é sugerido e foi riscado por @damkrat, pois a alteração me parece a maneira certa de resolver da maneira mais eficiente o problema subjacente de corrigir a confirmação incorreta, pois não há o propósito de não ter nenhuma inicial. confirmar. Como alguns enfatizaram, você só deve modificar o ramo "público" como mestre, se ninguém clonar seu repositório ...

git add <your different stuff>
git commit --amend --author="author name <[email protected]>"-m "new message"
Richard
fonte
- o autor é necessário apenas se alguém corrigir a autoria do commit
Richard
0

git reset --hard faça alterações, então faça

git add -A
git commit --amend --no-edit 

ou

git add -A
git commit --amend -m "commit_message"

e depois

git push origin master --force

--force reescreverá o commit que você redefiniu na primeira etapa.

Não faça isso, porque você está prestes a ir contra toda a idéia dos sistemas VCS e do git em particular. O único bom método é criar novos e excluir ramificações desnecessárias. Veja git help branchpara informações.

damkrat
fonte
-1

Tudo o que você precisa fazer é reverter o commit.

git revert {commit_id}'

Então empurre

git push origin -f
abdallah Nofal
fonte
Não é possível fazer isso no primeiro commit.
Usuário que não é usuário