Quando você usa
git rm --cached myfile
ele não exclui do sistema de arquivos local, que é o objetivo. Mas se você já fez a versão e comprometeu o arquivo, empurrou-o para um repositório central e o puxou para outro repositório antes de usar o comando, ele excluirá o arquivo desse sistema.
Existe uma maneira de simplesmente remover o arquivo do controle de versão sem excluí-lo de qualquer sistema de arquivos?
Edit: Esclarecido, espero.
git
version-control
gitignore
git-rm
Fletcher Moore
fonte
fonte
Respostas:
Eu não acho que um commit do Git possa registrar uma intenção como "pare de rastrear este arquivo, mas não o exclua".
A realização dessa intenção exigirá intervenção fora do Git em quaisquer repositórios que mesclem (ou se refiram a) uma confirmação que exclui o arquivo.
Salvar uma cópia, aplicar exclusão, restaurar
Provavelmente, a coisa mais fácil a fazer é dizer aos usuários downstream para salvar uma cópia do arquivo, retirar sua exclusão e restaurar o arquivo. Se eles estão recebendo via rebase e estão 'carregando' modificações no arquivo, eles terão conflitos. Para resolver esses conflitos, use
git rm foo.conf && git rebase --continue
(se a confirmação conflitante tiver alterações além daquelas no arquivo removido) ougit rebase --skip
(se a confirmação conflitante tiver sido alterada apenas no arquivo removido).Restaurar arquivo como não rastreado após obter uma confirmação que o exclui
Se eles já obtiveram seu commit de exclusão, ainda poderão recuperar a versão anterior do arquivo com o git show :
Ou com o git checkout (por comentário de William Pursell; lembre-se de removê-lo novamente do índice!):
Se eles executaram outras ações desde que você efetuou a exclusão (ou estão recuperando com rebase para um HEAD desanexado), podem precisar de algo diferente
@{1}
. Eles poderiam usargit log -g
para encontrar o commit antes de remover sua exclusão.Em um comentário, você menciona que o arquivo que você deseja “rastrear, mas manter” é algum tipo de arquivo de configuração necessário para executar o software (diretamente de um repositório).
Mantenha o arquivo como 'padrão' e ative-o manualmente / automaticamente
Se não for totalmente inaceitável continuar mantendo o conteúdo do arquivo de configuração no repositório, você poderá renomear o arquivo rastreado de (por exemplo)
foo.conf
parafoo.conf.default
e instruir seus usuárioscp foo.conf.default foo.conf
após aplicar a confirmação de renomeação. Ou, se os usuários já usam alguma parte existente do repositório (por exemplo, um script ou outro programa configurado pelo conteúdo no repositório (por exemplo,Makefile
ou similar)) para iniciar / implantar seu software, você pode incorporar um mecanismo padrão no lançamento / processo de implantação:Com tal mecanismo inadimplente no lugar, os usuários devem ser capazes de puxar um commit que renomeia
foo.conf
afoo.conf.default
sem ter que fazer qualquer trabalho extra. Além disso, você evita copiar manualmente um arquivo de configuração se criar instalações / repositórios adicionais no futuro.Reescrever o histórico requer intervenção manual de qualquer maneira…
Se é inaceitável manter o conteúdo no repositório, você provavelmente desejará erradicá-lo completamente da história com algo parecido
git filter-branch --index-filter …
. Isso equivale a reescrever o histórico, o que exigirá intervenção manual para cada filial / repositório (consulte a seção “Recuperando da recuperação upstream” na página de manual do git rebase ). O tratamento especial necessário para seu arquivo de configuração seria apenas mais uma etapa que você deve executar enquanto se recupera da reescrita:Ignore-o para impedir a recorrência
Qualquer que seja o método usado, você provavelmente incluirá o nome do arquivo de configuração em um
.gitignore
arquivo no repositório para que ninguém possa inadvertidamentegit add foo.conf
repetir (é possível, mas requer-f
/--force
). Se você tiver mais de um arquivo de configuração, considere 'movê-los' todos para um único diretório e ignorar tudo. o mecanismo de inicialização / implantação) para copiar / mover os arquivos para seu novo local; você obviamente não gostaria de colocar um arquivo mv em um diretório que você estará ignorando).fonte
--{,no-}assume-unchanged
é puramente local: seu estado não é registrado diretamente em confirmações. Ele pode ajudar a impedir que um repositório comprometa novas alterações no arquivo, mas não o remove do controle de versão. Se você pode configurá-lo para todos os seus repositórios relevantes, relacionados e não expostos, isso pode ajudar sua situação, mas não é algo que você poderia diretamente empurrar + puxar / rebase para outros repositórios não expostos relacionados (especialmente aqueles que você não controla, de acordo com os comentários esclarecedores do autor original sobre a questão: consulte “sistemas de pessoas” / “sistemas estrangeiros”).I do not think a Git commit can record an intention like “stop tracking this file, but do not delete it”.
- agora pode, comgit rm --cached foo.conf
Tive o mesmo problema nesta semana, quando acidentalmente cometi, tentei remover um arquivo de compilação de um repositório compartilhado, e isto:
http://gitready.com/intermediate/2009/02/18/temporariamente-ignoring-files.html
funcionou bem para mim e não foi mencionado até agora.
Para remover o arquivo do seu controle de versão, use todos os outros comandos normalmente.
Se você sempre quis colocá-lo de volta.
Editar: veja os comentários de Chris Johnsen e KPM, isso só funciona localmente e o arquivo permanece sob controle de versão para outros usuários se eles também não o fizerem. A resposta aceita fornece métodos mais completos / corretos para lidar com isso. Além disso, algumas notas do link se você usar este método:
fonte
Para remover o arquivo do índice, use:
Isso não deve afetar sua cópia local ou de qualquer outra pessoa.
fonte
reset
somente remove o arquivo do índice se o arquivo não estiver na confirmação HEAD atual, caso contrário, apenas reverterá a versão do índice para a versão HEAD atual.git rm --cached remove_file
git add .gitignore
git commit -m "Excluding"
fonte
Depois de executar o
git rm --cached
comando, tente adicionarmyfile
ao.gitignore
arquivo (crie um se ele não existir). Isso deve dizer ao git para ignorarmyfile
.O
.gitignore
arquivo é versionado, então você precisará confirmá-lo e enviá-lo ao repositório remoto.fonte
Minha solução é puxar a outra cópia de trabalho e depois:
que diz obter todos os caminhos de arquivo no último comentário e verificá-los do pai do HEAD. Tarefa concluída.
fonte
As soluções acima funcionam bem na maioria dos casos. No entanto, se você também precisar remover todos os rastreamentos desse arquivo (ou seja, dados confidenciais, como senhas), também será necessário removê-lo de todo o histórico de confirmação, pois o arquivo ainda poderá ser recuperado a partir daí.
Aqui está uma solução que remove todos os rastreamentos do arquivo de todo o seu histórico de consolidação, como se nunca tivesse existido, mantendo o arquivo no seu sistema.
https://help.github.com/articles/remove-sensitive-data/
Você pode realmente pular para a etapa 3 se estiver no seu repositório git local e não precisar executar uma execução a seco. No meu caso, eu só precisava das etapas 3 e 6, pois já havia criado meu arquivo .gitignore e estava no repositório em que queria trabalhar.
Para ver suas alterações, pode ser necessário acessar a raiz do GitHub do seu repositório e atualizar a página. Em seguida, navegue pelos links para acessar um commit antigo que já possuía o arquivo, para ver se ele foi removido. Para mim, simplesmente atualizar a página de confirmação antiga não mostrava a alteração.
Parecia intimidador a princípio, mas na verdade era fácil e funcionava como um encanto! :-)
fonte