Nota: o fallengamer fez alguns testes em 2011 (para que possam estar desatualizados), e aqui estão suas descobertas :
Operações
- O arquivo é alterado no repositório local e no upstream
git pull
: o
Git preserva as alterações locais de qualquer maneira.
Assim, você não perderia acidentalmente nenhum dado marcado com qualquer uma das bandeiras.
- Arquivo com
assume-unchanged
sinalizador: o Git não substitui o arquivo local. Em vez disso, geraria conflitos e conselhos sobre como resolvê-los
- Arquivo com
skip-worktree
sinalizador: o Git não substitui o arquivo local. Em vez disso, geraria conflitos e conselhos sobre como resolvê-los
- O arquivo é alterado no repositório local e no upstream, tentando puxar de qualquer maneira.
Usando resultados em algum trabalho manual extra, mas pelo menos você não perderia nenhum dado se tivesse alguma alteração local.
git stash
git pull
skip-worktree
- Arquivo com
assume-unchanged
sinalizador: descarta todas as alterações locais sem a possibilidade de restaurá-las. O efeito é como ' git reset --hard
'. ' git pull
' chamada terá sucesso
- Arquivo com
skip-worktree
sinalizador: o Stash não funcionaria em skip-worktree
arquivos. ' git pull
' falhará com o mesmo erro acima. O desenvolvedor é forçado a redefinir manualmente o skip-worktree
sinalizador para poder ocultar e concluir a falha pull
.
- Nenhuma alteração local, arquivo upstream alterado Os
dois sinalizadores não impediriam que você obtivesse alterações upstream. O Git detecta que você quebrou a promessa e escolheu refletir a realidade redefinindo a bandeira.
git pull
assume-unchanged
- Arquivo com
assume-unchanged
sinalizador: o conteúdo é atualizado, o sinalizador é perdido.
' git ls-files -v
' mostraria que o sinalizador é modificado para H
(de h
).
- Arquivo com
skip-worktree
sinalizador: o conteúdo é atualizado, o sinalizador é preservado.
' git ls-files -v
' mostraria a mesma S
bandeira de antes do pull
.
- Com o arquivo local alterado, o
Git não toca no arquivo e reflete a realidade (o arquivo que prometeu permanecer inalterado foi realmente alterado) para o arquivo.
git reset --hard
skip-worktree
assume-unchanged
- Arquivo com
assume-unchanged
sinalizador: o conteúdo do arquivo é revertido. O sinalizador é redefinido para H
(de h
).
- Arquivo com
skip-worktree
sinalizador: o conteúdo do arquivo está intacto. A bandeira permanece a mesma.
Ele adiciona a seguinte análise:
Parece que skip-worktree
está tentando muito preservar seus dados locais . Mas isso não impede que você receba alterações upstream, se for seguro. Além disso, o git não redefine a bandeira pull
.
Mas ignorar o reset --hard
comando ' ' pode se tornar uma surpresa desagradável para um desenvolvedor.
Assume-unchanged
A flag pode ser perdida na pull
operação e as alterações locais dentro desses arquivos não parecem ser importantes para o git.
Vejo:
Ele conclui:
Na verdade, nenhuma das bandeiras é intuitiva o suficiente .
assume-unchanged
assume que um desenvolvedor não deve alterar um arquivo. Se um arquivo foi alterado - essa alteração não é importante. Esse sinalizador é destinado a melhorar o desempenho de pastas que não mudam, como SDKs.
Mas se a promessa for quebrada e um arquivo for realmente alterado, o git reverte a flag para refletir a realidade. Provavelmente, não há problema em ter alguns sinalizadores inconsistentes em pastas que geralmente não devem ser alteradas.
Por outro lado, skip-worktree
é útil quando você instrui o git a nunca tocar em um arquivo específico. Isso é útil para um arquivo de configuração já rastreado.
O repositório principal upstream hospeda algumas configurações prontas para produção, mas você gostaria de alterar algumas configurações na configuração para poder fazer alguns testes locais. E você não deseja verificar acidentalmente as alterações nesse arquivo para afetar a configuração de produção. Nesse caso, skip-worktree
faz cena perfeita.
Com o Git 2.25.1 (fevereiro de 2020), o "Na verdade nenhum dos sinalizadores é intuitivo o suficiente" mencionado acima é esclarecido:
Consulte commit 7a2dc95 , commit 1b13e90 (22 jan 2020) por brian m. Carlson ( bk2204
) .
(Mesclado por Junio C Hamano - gitster
- no commit 53a8329 , 30 de janeiro de 2020)
( lista de discussão do Git )
doc
: dissuadir os usuários de tentar ignorar arquivos rastreados
Assinado por: Jeff King
Assinado por: brian m. Carlson
É bastante comum os usuários quererem ignorar as alterações em um arquivo que o Git rastreia.
Os cenários comuns para esse caso são as configurações e os arquivos de configuração do IDE, que geralmente não devem ser rastreados e possivelmente gerados a partir de arquivos rastreados usando um mecanismo de modelo.
No entanto, os usuários aprendem sobre os bits assumir-inalterados e ignorar-worktree e tentam usá-los para fazer isso de qualquer maneira.
Isso é problemático porque, quando esses bits são definidos, muitas operações se comportam conforme o usuário espera, mas geralmente não ajudam quando é git checkout
necessário substituir um arquivo.
Não há comportamento sensível nesse caso, porque algumas vezes os dados são preciosos, como certos arquivos de configuração, e outras são dados irrelevantes que o usuário ficaria feliz em descartar.
Como essa não é uma configuração suportada e os usuários tendem a usar incorretamente os recursos existentes para fins não intencionais, causando tristeza e confusão geral , vamos documentar o comportamento existente e as armadilhas na documentação para git update-index
que os usuários saibam que devem explorar soluções alternativas.
Além disso, vamos fornecer uma solução recomendada para lidar com o caso comum de arquivos de configuração, pois existem abordagens conhecidas usadas com sucesso em muitos ambientes.
A git update-index
página de manual agora inclui:
Os usuários geralmente tentam usar os bits assume-unchanged
e skip-worktree
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.
Por exemplo, se o arquivo que você deseja alterar for algum tipo de arquivo de configuração, o repositório poderá incluir um arquivo de configuração de amostra que poderá ser copiado para o nome ignorado e modificado. O repositório pode até incluir um script para tratar o arquivo de amostra como um modelo, modificando e copiando-o automaticamente.
Essa última parte é o que descrevo um driver típico de filtro de conteúdo com base em scripts smudge / clean .
.gitignore
para fins semelhantes. Essa solução funcionaria para você?