Estou usando o Git e comprometi alguns arquivos usando
git commit -a
Mais tarde, descobri que um arquivo foi adicionado por engano ao commit.
Como posso remover um arquivo da última confirmação?
git reset filepath
Estou usando o Git e comprometi alguns arquivos usando
git commit -a
Mais tarde, descobri que um arquivo foi adicionado por engano ao commit.
Como posso remover um arquivo da última confirmação?
git reset filepath
Respostas:
Eu acho que outras respostas aqui estão erradas, porque essa é uma questão de mover os arquivos confirmados por engano de volta para a área de preparação do commit anterior, sem cancelar as alterações feitas neles. Isso pode ser feito como sugerido por Paritosh Singh:
git reset --soft HEAD^
ou
git reset --soft HEAD~1
Redefina os arquivos indesejados para excluí-los da confirmação:
git reset HEAD path/to/unwanted_file
Agora confirme novamente, você pode até reutilizar a mesma mensagem de confirmação:
git commit -c ORIG_HEAD
git push
consertar seu repo, ele irá reclamar Updates were rejected because the tip of your current branch is behind its remote counterpart.
. Se você tem certeza de que deseja empurrá-los (por exemplo, é o seu garfo), pode usar a -f
opção para forçar o empurrão, por exemplo git push origin master -f
. (Não faça isto a um repo montante que os outros estão buscando de)
git reset --soft HEAD^
é a minha mais comum de desfazer a operação
git reset
mas queria uma maneira de afetar o commit existente "no local". Eu acabei de aprender git commit -C
. Então, para mim, o que eu quero é sua receita exata com mais uma etapa, o "novo commit novamente" explicitado como git commit -C [hash of original HEAD commit from first step]
.
ATENÇÃO ! Se você deseja apenas remover um arquivo do commit anterior e mantê-lo em disco , leia a resposta do juzzlin logo acima.
Se este é seu último commit e você deseja excluir completamente o arquivo do repositório local e remoto , você pode:
git rm <file>
git commit --amend
O sinalizador de alteração diz ao git para confirmar novamente, mas "mescla" (não no sentido de mesclar duas ramificações) esse commit com o último commit.
Conforme declarado nos comentários, usar git rm
aqui é como usar o rm
próprio comando!
git rm --cached
para manter os arquivos no disco
rm
no git
comando está fazendo o que rm
em si faz!
git commit --amend
ainda está lá e pode ser encontrado, por exemplo, com git reflog
. Portanto, não é tão ruim quanto os outros comentários sugerem.
As respostas existentes estão falando sobre remover os arquivos indesejados da última confirmação.
Se você deseja remover arquivos indesejados de uma confirmação antiga (mesmo enviada por push) e não deseja criar uma nova confirmação, o que é desnecessário, devido à ação:
1
Encontre a confirmação com a qual você deseja que o arquivo esteja em conformidade.
git checkout <commit_id> <path_to_file>
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 por engano , digamos "35c23c2" aqui
git rebase 35c23c2~1 -i // notice: "~1" is necessary
Este comando abre o editor de acordo com as suas configurações. O padrã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 defina 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, infelizmente, você tiver conflitos, precisará resolvê-los manualmente.
git rm --cached <file(s)>
.
--fixup=35c23c2
ao git commit
comando Isso configurará a confirmação automaticamente como uma correção da confirmação necessária e, portanto, você não precisará especificá-lo na nova base. Além disso, se você adicionar --autosquash
ao git rebase
comando, o git moverá automaticamente o seu commit para o local correto, para que você não precise fazer nada no rebase interativo - salve o resultado (o que significa que você nem precisa -i
sinalizar, embora eu goste de usá-lo de qualquer maneira para garantir que tudo esteja como eu esperava).
Como a resposta aceita indica, você pode fazer isso redefinindo todo o commit. Mas essa é uma abordagem bastante pesada.
Uma maneira mais limpa de fazer isso seria manter a confirmação e simplesmente remover os arquivos alterados.
git reset HEAD^ -- path/to/file
git commit --amend --no-edit
Ele git reset
pegará o arquivo como estava na confirmação anterior e o preparará no índice. O arquivo no diretório de trabalho é intocado.
O git commit
irá confirmar e compactar o índice no commit atual.
Essencialmente, pega a versão do arquivo que estava na confirmação anterior e a adiciona à confirmação atual. Isso resulta em nenhuma alteração líquida e, portanto, o arquivo é efetivamente removido da confirmação.
Se você não enviou as alterações no servidor, pode usar
git reset --soft HEAD~1
Ele redefinirá todas as alterações e reverterá para uma confirmação
Se você enviou suas alterações, siga as etapas conforme respondidas por @CharlesB
Remover o arquivo usando rm o excluirá!
Você está sempre adicionando a uma confirmação no git, em vez de removê-la, portanto, nesse caso, retorne o arquivo ao estado em que estava antes da primeira confirmação (pode ser uma ação de exclusão 'rm' se o arquivo for novo) e, em seguida, re-confirmar e o arquivo irá.
Para retornar o arquivo para algum estado anterior:
git checkout <commit_id> <path_to_file>
ou para devolvê-lo ao estado no HEAD remoto:
git checkout origin/master <path_to_file>
em seguida, corrija o commit e você deverá encontrar o arquivo desaparecido da lista (e não excluído do seu disco!)
git checkout HEAD~ path/to/file
git commit --amend
O seguinte mostrará o estágio do arquivo pretendido, que é o que o OP pediu.
git reset HEAD^ /path/to/file
Você verá algo como o seguinte ...
Alterações a serem confirmadas: (use "git reset HEAD ..." para unstage)
modificado: / caminho / para / arquivo
Alterações não preparadas para confirmação: (use "git add ..." para atualizar o que será confirmado) (use "git checkout - ..." para descartar as alterações no diretório de trabalho)
modificado: / caminho / para / arquivo
Nesse ponto, você pode fazer o que quiser no arquivo, como redefinir para uma versão diferente.
Quando você estiver pronto para confirmar:
git commit --amend -a
ou (se você tiver outras alterações que ainda não deseja confirmar)
git commit add /path/to/file
git commit --amend
Vou explicar para você com exemplo.
Sejam A, B, C três confirmações sucessivas. A confirmação 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-with-lease <branchName>
noop
para edit [A_commit_ID]
oue [A_commit_ID]
Você pode simplesmente tentar.
git reset --soft HEAD~1
e crie um novo commit.
No entanto, existe um incrível software "gitkraken". o que facilita o trabalho com o git.
git commit --amend
para que a remoção do arquivo fosse atualizada no seu último commit; e depois, você pode verificar se ele foi realmente removido comgit log -1 --stat
git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "removed unwanted file from git"
deixará o arquivo local ainda. Se você também não deseja o arquivo localmente, pode pular a opção --cached.
Se todo o trabalho estiver em sua filial local, você precisará manter o arquivo em uma consolidação posterior e, como um histórico limpo, acho que uma maneira mais simples de fazer isso:
git rm --cached <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit --squash <commit_id>
git add <file_to_remove_from_commit_<commit_id>_which_added_file>
git commit -m "brand new file!"
git rebase --interactive <commit_id>^
e, em seguida, você pode concluir o rebase com facilidade, sem precisar se lembrar de comandos mais complexos ou confirmar a mensagem ou digitar o mesmo.
O uso da GUI do git 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 reescrever o histórico , execute:
git gui citool --amend
Você pode desmarcar o arquivo que foi confirmado por engano e clicar em "Confirmar".
O arquivo é removido da confirmação, mas será mantido no disco . Portanto, se você desmarcou o arquivo após adicioná-lo por engano, ele será exibido na sua lista de arquivos não rastreados (e se você desmarcou o arquivo após modificá-lo por engano, ele será exibido nas alterações que não foram preparadas para a lista de confirmação).
sudo apt-get install git-gui
git rebase -i HEAD~4
e depois executei seu comando para abrir o editor. Outra observação: "Unstaging" pode ser encontrado no menu "Commit".
git reset --soft HEAD^
(lembrando-se do --soft arg), seguido por git commit -c ORIG_HEAD
(em vez de --amend, que estraga tudo).
Se você deseja preservar seu commit (talvez você já tenha passado algum tempo escrevendo uma mensagem de commit detalhada e não queira perdê-lo), e só deseja remover o arquivo do commit, mas não inteiramente do repositório:
git checkout origin/<remote-branch> <filename>
git commit --amend
Execute 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 `<your file>`
//finally make a new commit
git commit -m 'Your message'
Só queria complementar a resposta superior, pois tive que executar um comando extra:
git reset --soft HEAD^
git checkout origin/master <filepath>
Felicidades!
Algo que funcionou para mim, mas ainda acho que deveria haver uma solução melhor:
$ git revert <commit_id>
$ git reset HEAD~1 --hard
Apenas deixe a alteração que deseja descartar no outro commit, confira outros
$ git commit --amend // or stash and rebase to <commit_id> 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ê quer ir)
e então, 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 tenho alterações em uma filial local em que 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 para um arquivo específico)
( origin / feature / target_branch é a ramificação remota para a qual desejo enviar minhas alterações)
(o recurso / armazenamento temporário é meu ramo de armazenamento temporário, onde enviarei todas as alterações desejadas, excluindo a alteração nesse arquivo)
Crie uma filial local a partir da minha origem / recurso / target_branch - chamada de recurso / estadiamento
Mesclou meu recurso de filial local de trabalho / target_branch à filial de recurso / preparo
Efetuou check-out do recurso / teste e git reset --soft ORIG_HEAD (Agora todas as alterações do recurso / teste 'serão testadas, mas não confirmadas.)
Desempenhou o arquivo que eu registrei anteriormente com alterações desnecessárias
Foi alterada a ramificação upstream do recurso / preparação para origem / recurso / target_branch
Confirmei o restante das alterações em etapas e enviei a montante para minha origem / recurso / target_branch remoto
Se você estiver usando o GitHub e ainda não enviou a confirmação, o GitHub Desktop resolve esse problema facilmente:
Se você deseja remover arquivos de confirmações anteriores, use filtros
git filter-branch --prune-empty --index-filter 'git rm --ignore-unmatch --cached "file_to_be_removed.dmg"'
Se você vir este erro:
Não é possível criar um novo backup. Um backup anterior já existe em refs / original / Force sobrescrevendo o backup com -f
Basta remover os backups de refs no seu repositório local
$ rm -rf .git/refs/original/refs
se você não enviar suas alterações para o git ainda
git reset --soft HEAD~1
Ele redefinirá todas as alterações e reverterá para uma confirmação
Se este é o último commit que você fez e deseja excluir o arquivo do repositório local e remoto, tente o seguinte:
git rm <file>
git commit --amend
ou melhor ainda:
redefinir primeiro
git reset --soft HEAD~1
redefinir o arquivo indesejado
git reset HEAD path/to/unwanted_file
comprometer novamente
git commit -c ORIG_HEAD
Here is the step to remove files from Git Commit.
>git reset --soft HEAD^1(either commitid ) -- now files moved to the staging area.
>git rm --cached filename(it will removed the file from staging area)
>git commit -m 'meaningfull message'(Now commit the required files)
Nenhuma das respostas no momento é razoável. Parece que há demanda suficiente para que uma solução real seja proposta: https://github.com/git/git/blob/master/Documentation/SubmittingPatches
git --uncommit <nome do arquivo>
seria bom. Entendo que não queremos modificar o histórico, mas se eu for local e adicionar acidentalmente o arquivo "hack" local e quiser removê-lo do commit, isso seria super útil.