Mantenha o arquivo em um repositório Git, mas não rastreie as alterações

305

Eu tenho vários arquivos em um site CodeIgniter que desejarei ter no repositório, mas não acompanho nenhuma alteração.

Por exemplo, implanto uma nova instalação dessa estrutura em um novo cliente, desejo que os seguintes arquivos sejam baixados (eles têm valores padrão CHANGEME) e só preciso fazer alterações específicas para esse cliente (credenciais do banco de dados, informações de endereço de email, CSS customizado).

// the production config files i want the files but they need to be updated to specific client needs
application/config/production/config.php
application/config/production/database.php
application/config/production/tank_auth.php
// index page, defines the environment (production|development)
/index.php
// all of the css/js cache (keep the folder but not the contents)
/assets/cache/*
// production user based styling (color, fonts etc) needs to be updated specific to client needs
/assets/frontend/css/user/frontend-user.css

Atualmente, se eu correr

git clone [email protected]:user123/myRepo.git httpdocs

e edite os arquivos acima, tudo está ótimo. Até eu lançar um hotfix ou patch e executar git pull. Todas as minhas alterações são substituídas.

gorelativo
fonte
Você pode simplesmente ignorar os arquivos de credencial / configuração do cliente e fazer com que o programa construa os arquivos padrão se eles estiverem ausentes quando o repositório for instalado?
MatthewG

Respostas:

618

O git tem uma solução diferente para fazer isso. Primeiro mude o arquivo que você não deseja que seja rastreado e use o seguinte comando:

git update-index --assume-unchanged FILE_NAME

e se você deseja rastrear as alterações novamente, use este comando:

git update-index --no-assume-unchanged FILE_NAME

Documentação do git-update-index

nasirkhan
fonte
Eu fiz o que você diz, mas git status continuo dizendo que o arquivo é modificado
rraallvv
7
Sim, essa deve ser a "resposta aceita". Trabalhou para mim.
Joshmcode #
34
De acordo com Junio ​​Hamano (o mantenedor do Git): "Suponha que a alteração inalterada não deve ser abusada por um mecanismo de ignorar. [...] não é uma promessa do Git que o Git sempre considere que esses caminhos não são modificados --- se o Git pode determinar um caminho marcado como alterado sem assumir alterações sem incorrer em custos adicionais do lstat (2), reserva-se o direito de informar que o caminho foi modificado (como resultado, "git commit -a" está livre para confirmar que mudança)." Em outras palavras, assumir que inalterado é apenas para problemas de desempenho local. Se o Git puder determinar que esses arquivos foram alterados de uma maneira mais leve, será.
Alejandro García Iglesias
41
Lendo as informações, acho que a --skip-worktreeopção é mais adequada para esse trabalho do que --assume-unchanged.
PJSCopeland
26
--skip-worktree é realmente a melhor opção. Mais informações: stackoverflow.com/questions/13630849/…
Customizer
80

Para extrair uma resposta dos comentários de outra resposta:

$ git update-index --skip-worktree FILENAME

Parece ser uma opção melhor do que --assume-unchanged

Pode-se ler mais sobre isso aqui: Git - Diferença entre 'assumir-inalterado' e 'ignorar-área de trabalho'

Anthony
fonte
Quando faço isso e tento alterar ramificações, recebo "Os seguintes arquivos da árvore de trabalho não rastreados serão substituídos pelo checkout ... Mova ou remova-os antes de alternar ramificações". Alguma idéia de como evitar?
Patrick Szalapski 02/12/19
O artigo referenciado por @aexl foi movido para compiledsuccessfully.dev/git-skip-worktree
Andrew Keeton
1
Os médicos dizem que essa é uma má ideia. "Os usuários geralmente tentam usar os bits assumir-inalterados e ignorar-árvore de trabalho para dizer ao Git para ignorar as alterações nos arquivos rastreados. Isso não funciona como esperado, pois o Git ainda pode verificar os arquivos da árvore de trabalho em relação ao índice ao executar determinadas operações. Em geral, o Git não fornece uma maneira de ignorar as alterações nos arquivos rastreados, portanto, soluções alternativas são recomendadas ".
Curtis Blackwell
58

Para meus projetos do Code Igniter, mantenho database.php.example e config.php.example no repositório.

Em seguida, adiciono config.php e applications / config / database.php ao arquivo .gitignore .

Então, finalmente, quando implanto, posso copiar os arquivos .example (para config.php e database.php), personalizá-los e eles não serão rastreados pelo GIT.

superiggy
fonte
12
Solução agradável, mas acho que a resposta de nasirkhan é a melhor.
wordsforthewise
Esta não é uma boa solução. Se você liberar seu índice git, começará a rastrear as alterações quando não pretender. Veja a resposta @nasirkhans para a maneira correta de fazer isso.
Brian Melton-Grace - MSFT
3
Não concordo com os dois comentários anteriores. Dessa forma, é muito mais fácil atualizar os valores "padrão" sem precisar fazer check-out deles e copiar sua configuração local em outro lugar apenas para recuperá-la depois. Além disso, ele se aplica a todos os repositórios para que você não precise fazer repetidas alterações de repositório.
OskarD90
1
se estiver no gitignore, por que começaria a rastrear as alterações novamente
Shapeshifter
Resolve o problema do OP, mas na verdade não responde à pergunta.
Travis Wilson
1

Eu os colocava no seu .gitignorearquivo e apenas os copiava manualmente, conforme necessário.

Portanto, o nome do arquivo do esqueleto estaria no git, os nomes de arquivos ignorados não estariam no git (mas em .gitignore). Dessa forma, quando a etapa manual para copiá-los para 'real' do 'modelo' (melhor nome do que esqueleto, talvez) for concluída, eles serão imediatamente ignorados.

Michael Durrant
fonte
1
não há como adicioná-los ao repositório primeiro e depois ao .gitignore? Seria ótimo se houvesse uma solução para isso incluir os arquivos, mas nenhuma alteração após uma determinada confirmação ou algo assim.
gorelative
1
@mklauber Quero mantê-los indefinidamente até que eu corra git rm <file>. O objetivo é o IE: um arquivo config.php. Eu quero manter o arquivo de configuração, mas obviamente não quero rastrear as credenciais do banco de dados de cliente para cliente, pois são diferentes.
gorelative
1
Sim, tenho o problema com nosso arquivo database.yml do rails. Mantemos um esqueleto, copiamos e mudamos.
Michael Durrant
se eu criar esses arquivos de configuração "Skeleton", você os adicionaria a uma confirmação inicial. e modificando .gitignore para ignorar o arquivo? Com efeito, mantendo o arquivo no repositório, mas como um esqueleto?
gorelative
10
Você tem estas duas opções: Adicione o arquivo git add file1e edite-o .gitignore. O arquivo confirmado permanecerá lá e não será atualizado. Ou: Você pode adicionar o arquivo para .gitignoree, em seguida, adicioná-lo com git add --force file1para forçar o arquivo em Você pode usar a segunda opção sempre que você tem que substituir o arquivo.
klaustopher
1

As respostas dadas estão resolvendo o problema apenas parcialmente, mas introduzindo ainda mais problemas.

Eu precisava preservar o arquivo "Web.Local.config". A única solução que funcionou para mim foi:

1. Excluir o arquivo do projeto

2. Crie uma cópia separada do arquivo como Web.LocalTemplate.config

Agora que o "Web.LocalTemplate.config" é rastreado pelo Git, todos os desenvolvedores podem usá-lo como ponto de partida. No entanto, o "Web.Local.config", que não faz parte do projeto, será automaticamente ignorado.

Hrvoje Matić
fonte
Como é git update-index --skip-worktree FILENAMEresolver apenas parcialmente o seu problema, ou até adicionar mais problemas? Resolve exatamente o que você está tentando fazer. Você tentou?
Amir Asyraf 23/07/19