Remover arquivos do Git commit

Eu estou usando o Git e eu cometi poucos arquivos usando

git commit -a 

Mais tarde, descobri que um arquivo foi adicionado por engano ao commit.

Como posso remover um arquivo do último commit?

Acho que outras respostas aqui estão erradas, porque essa é uma questão de mover os arquivos comprometidos por engano de volta para a área de preparação da confirmação anterior, sem cancelar as alterações feitas neles. Isso pode ser feito como Paritosh Singh sugeriu:

 git reset --soft HEAD^ 

ou

 git reset --soft HEAD~1 

Em seguida, redefina os arquivos indesejados para deixá-los fora do commit:

 git reset HEAD path/to/unwanted_file 

Agora commit novamente, você pode até mesmo reutilizar a mesma mensagem de commit:

 git commit -c ORIG_HEAD 

ATENÇÃO ! Se você quiser apenas remover um arquivo da sua confirmação anterior e mantê-lo no disco , leia a resposta de juzzlin logo acima.

Se este for seu último commit e você quiser excluir completamente o arquivo do seu repository local e remoto , você pode:

  1. remova o arquivo git rm
  2. commit com o sinalizador de alteração: git commit --amend

O sinalizador de alteração diz ao git para confirmar novamente, mas “mesclar” (não no sentido de mesclar dois ramos) este commit com o último commit.

Como dito nos comentários, usar o git rm aqui é como usar o próprio comando rm !

Respostas existentes estão falando sobre como remover os arquivos indesejados do último commit.

Se você quiser remover arquivos indesejados de um commit antigo (até mesmo pressionado) e não quiser criar um novo commit, o que é desnecessário, por causa da ação:

1

Encontre o commit que você deseja que o arquivo esteja em conformidade.

 git checkout   

você pode fazer isso várias vezes se quiser remover muitos arquivos.

2

 git commit -am "remove unwanted files" 

3

Encontre o commit_id do commit no qual os arquivos foram adicionados erroneamente , digamos “35c23c2” aqui

 git rebase 35c23c2~1 -i // notice: "~1" is necessary 

Este comando abre o editor de acordo com suas configurações. O padrão é o vim.

Mova o último commit, que deve ser “remover arquivos indesejados”, para a próxima linha do commit incorreto (“35c23c2” no nosso caso), e configure o comando como fixup :

 pick 35c23c2 the first commit fixup 0d78b28 remove unwanted files 

Você deve ser bom depois de salvar o arquivo.

Terminar :

 git push -f 

Se você, infelizmente, obtiver conflitos, terá que resolvê-los manualmente.

Como a resposta aceita indica, você pode fazer isso redefinindo todo o commit. Mas esta é uma abordagem bastante pesada.
Uma maneira mais limpa de fazer isso seria manter o commit e simplesmente remover os arquivos alterados dele.

 git reset HEAD^ -- path/to/file git commit --amend --no-edit 

A git reset o arquivo como estava no commit anterior e o colocará no índice. O arquivo no diretório de trabalho está intacto.
O git commit irá então confirmar e esmagar o índice no commit atual.

Isso essencialmente pega a versão do arquivo que estava no commit anterior e o adiciona ao commit atual. Isso resulta em nenhuma alteração de rede e, portanto, o arquivo é efetivamente removido da confirmação.

Se você não tiver pressionado as alterações no servidor, poderá usar

 git reset --soft HEAD~1 

Ele irá redefinir todas as alterações e reverter para um commit de volta

Se você tiver pressionado suas alterações, siga as etapas respondidas por @CharlesB

Remover o arquivo usando rm irá apagá-lo!

Você está sempre adicionando a um commit no git ao invés de remover, então nesta instância retorne o arquivo para o estado em que estava antes do primeiro commit (isso pode ser uma ação delete ‘rm’ se o arquivo é novo) e então re-commit e o arquivo irá.

Para retornar o arquivo para algum estado anterior:

  git checkout   

ou para devolvê-lo ao estado na cabeça remota:

  git checkout origin/master  

Em seguida, alterar o commit e você deve encontrar o arquivo desapareceu da lista (e não excluído do seu disco!)

 git checkout HEAD~ path/to/file git commit --amend 

O seguinte irá unstage apenas o arquivo que você pretendia, que é o que o OP pediu.

 git reset HEAD^ /path/to/file 

Você verá algo como o seguinte …

Alterações a serem cometidas: (use “git reset HEAD …” para unstage)

modificado: / caminho / para / arquivo

Mudanças não preparadas para commit: (use “git add …” para atualizar o que será confirmado) (use “git checkout – …” para descartar as mudanças no diretório de trabalho)

modificado: / caminho / para / arquivo

  • “Alterações a serem confirmadas” é a versão anterior do arquivo antes do commit. Isso será parecido com uma exclusão se o arquivo nunca existiu. Se você confirmar essa alteração, haverá uma revisão que reverte a alteração no arquivo em sua ramificação.
  • “Alterações não preparadas para confirmação” é a alteração que você cometeu e o estado atual do arquivo

Neste ponto, você pode fazer o que quiser no arquivo, como redefinir para uma versão diferente.

Quando você estiver pronto para cometer:

 git commit --amend -a 

ou (se você tem outras mudanças acontecendo que você não quer cometer, ainda)

 git commit add /path/to/file git commit --amend 

Se você quiser preservar seu commit (talvez você já tenha passado algum tempo escrevendo uma mensagem de commit detalhada e não queira perdê-la), e você só quer remover o arquivo do commit, mas não do repository inteiramente:

 git checkout origin/  git commit --amend 
 git rm --cached _which_added_file> git commit -m "removed unwanted file from git" 

vai deixar você o arquivo local ainda. Se você não quiser o arquivo localmente, você pode pular a opção –cached.

Se todo o trabalho está em sua filial local, você precisa manter o arquivo em um commit posterior, e como ter um histórico limpo, eu acho que uma maneira mais simples de fazer isso poderia ser:

 git rm --cached _which_added_file> git commit --squash  git add _which_added_file> git commit -m "brand new file!" git rebase --interactive ^ 

e você pode terminar o rebase com facilidade sem precisar lembrar de comandos mais complexos ou enviar mensagens ou digitar muito.

Eu explicarei a você com exemplo.
Seja A, B, C como 3 commits sucessivos. Commit B contém um arquivo que não deveria ter sido confirmado.

 git log # take A commit_id git rebase -i "A_commit_ID" # do an interactive rebase change commit to 'e' in rebase vim # means commit will be edited git rm unwanted_file git rebase --continue git push --force  

Usar o git GUI pode simplificar a remoção de um arquivo da confirmação anterior.

Supondo que este não seja um ramo compartilhado e você não se importe em rewrite o histórico , execute:

 git gui citool --amend 

Você pode desmarcar o arquivo que foi confirmado por engano e clicar em “Confirmar”.

insira a descrição da imagem aqui

O arquivo é removido do commit, mas será mantido em disco . Portanto, se você desmarcou o arquivo após adicioná-lo por engano, ele será exibido na lista de arquivos não acompanhados (e, se você desmarcou o arquivo após modificá-lo por engano, ele será exibido em suas alterações não organizadas para a lista de confirmação).

Faça uma sequência dos seguintes comandos:

 //to remove the last commit, but preserve changes git reset --soft HEAD~1 //to remove unneded file from the staging area git reset HEAD `` //finally make a new commit git commit -m 'Your message' 

Só queria complementar a resposta principal como eu tive que executar um comando extra:

 git reset --soft HEAD^ git checkout origin/master  

Felicidades!

Algo que funcionou para mim, mas ainda acho que deveria haver uma solução melhor:

 $ git revert  $ git reset HEAD~1 --hard 

Apenas deixe a mudança que você quer descartar no outro commit, confira os outros

 $ git commit --amend // or stash and rebase to  to amend changes 

Na verdade, acho que uma maneira mais rápida e fácil é usar o modo interativo git rebase.

 git rebase -i head~1 

(ou cabeça ~ 4, até onde você quiser ir)

e depois, em vez de “escolher”, use “editar”. Eu não percebi o quão poderoso ‘editar’ é.

https://www.youtube.com/watch?v=2dQosJaLN18

Espero que você ache útil.

Tive o mesmo problema em que eu tinha alterações em uma ramificação local onde eu queria reverter apenas um arquivo. O que funcionou para mim foi –

( feature / target_branch abaixo é onde eu tenho todas as minhas alterações, incluindo aquelas que eu queria desfazer em um arquivo específico)

( origem / recurso / target_branch é o ramo remoto para onde eu quero enviar minhas alterações)

( feature / staging é o meu ramo temporário onde eu estarei empurrando de todas as minhas mudanças desejadas excluindo a mudança para aquele arquivo)

  1. Criar um ramo local a partir da minha origem / recurso / target_branch – chamado de recurso / teste

  2. Mesclou meu recurso de ramificação local / target_branch no recurso / ramo de preparação

  3. Recurso check out / staging, em seguida, git reset –soft ORIG_HEAD (Agora, todas as alterações do recurso / staging ‘serão testadas, mas não confirmadas.)

  4. Desvendou o arquivo que eu verifiquei anteriormente com alterações desnecessárias

  5. Mudou o ramo de upstream para feature / staging para origin / feature / target_branch

  6. Comprometido com o restante das alterações preparadas e enviado para a minha origem / recurso / target_branch remoto

git reset --soft HEAD^ retorna seu commit, e quando você digita git status , ele diz o que fazer:

 Changes to be committed: (use "git reset HEAD ..." to unstage) 

Se você não precisa mais desse arquivo, você poderia fazer

 git rm file git commit --amend git push origin branch 

Se você está usando o GitHub e ainda não enviou o commit, o GitHub Desktop resolve esse problema facilmente:

  1. Escolha Repository -> Undo Most Recent Commit
  2. Desmarque o arquivo que você adicionou por engano. Sua mensagem de confirmação anterior já estará na checkbox de diálogo.
  3. Pressione o botão Commit!

Isso é trabalhado para eu remover o arquivo do repository de repositorys de bits, que enviei inicialmente para o arquivo.

 git checkout origin/develop  git add  git commit -m "Message" git push