Tenho alterações locais em um arquivo que não quero confirmar no meu repositório. É um arquivo de configuração para criar o aplicativo em um servidor, mas quero criar localmente com configurações diferentes. Naturalmente, o arquivo sempre aparece quando eu faço o 'status git' como algo a ser preparado. Gostaria de ocultar essa alteração específica e não a comprometer. Não farei outras alterações no arquivo.
Depois de algumas investigações, vejo duas opções: 'assume inalterado' e 'pula a árvore de trabalho'. Uma pergunta anterior aqui fala sobre eles, mas realmente não explica suas diferenças. Minha pergunta é a seguinte: como os dois comandos são diferentes? Por que alguém usaria um ou outro?
.gitignore
para fins semelhantes. Essa solução funcionaria para você?Respostas:
Você quer
skip-worktree
.assume-unchanged
foi projetado para casos em que é caro verificar se um grupo de arquivos foi modificado; quando você define o bit,git
(é claro) assume que os arquivos correspondentes a essa parte do índice não foram modificados na cópia de trabalho. Portanto, evita uma confusão destat
chamadas. Este bit é perdido sempre que a entrada do arquivo no índice é alterada (portanto, quando o arquivo é alterado upstream).skip-worktree
é mais do que isso: mesmo quandogit
sabe que o arquivo foi modificado (ou precisa ser modificado por umreset --hard
ou algo semelhante), ele fingirá que não o foi, usando a versão do índice. Isso persiste até que o índice seja descartado.Há um bom resumo das ramificações dessa diferença e dos casos de uso típicos aqui: http://fallengamer.livejournal.com/93321.html .
Desse artigo:
--assume-unchanged
assume que um desenvolvedor não deve alterar um arquivo. Esse sinalizador destina-se a melhorar o desempenho de pastas que não mudam, como SDKs.--skip-worktree
é útil quando você instrui o git a não tocar em um arquivo específico, porque os desenvolvedores devem alterá-lo. Por exemplo, se o repositório principal upstream hospedar alguns arquivos de configuração prontos para produção e você não desejar confirmar acidentalmente alterações nesses arquivos,--skip-worktree
é exatamente o que você deseja.fonte
--skip-worktree
efeitos e desmarcar a bandeira, existe a--no-skip-worktree
opção. Funciona exatamente da mesma maneira. Isso é útil caso uma mão tenha escorregado e arquivos errados tenham sido sinalizados ou se as circunstâncias tenham mudado e os arquivos anteriormente ignorados não devam mais ser ignorados.--skip-worktree
e o.git/info/exclude
arquivo é que o primeiro funcionará mesmo para os arquivos rastreados no momento..git/info/exclude
, como.gitignore
, impedirá a adição acidental de arquivos não rastreados ao índice, mas não fará alterações nos arquivos já rastreados.git update-index --skip-worktree <file_name>
Nota: o fallengamer fez alguns testes em 2011 (para que possam estar desatualizados), e aqui estão suas descobertas :
Operações
git pull
: oGit preserva as alterações locais de qualquer maneira.
Assim, você não perderia acidentalmente nenhum dado marcado com qualquer uma das bandeiras.
assume-unchanged
sinalizador: o Git não substitui o arquivo local. Em vez disso, geraria conflitos e conselhos sobre como resolvê-losskip-worktree
sinalizador: o Git não substitui o arquivo local. Em vez disso, geraria conflitos e conselhos sobre como resolvê-losgit stash
git pull
skip-worktree
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á sucessoskip-worktree
sinalizador: o Stash não funcionaria emskip-worktree
arquivos. 'git pull
' falhará com o mesmo erro acima. O desenvolvedor é forçado a redefinir manualmente oskip-worktree
sinalizador para poder ocultar e concluir a falhapull
.git pull
assume-unchanged
assume-unchanged
sinalizador: o conteúdo é atualizado, o sinalizador é perdido.'
git ls-files -v
' mostraria que o sinalizador é modificado paraH
(deh
).skip-worktree
sinalizador: o conteúdo é atualizado, o sinalizador é preservado.'
git ls-files -v
' mostraria a mesmaS
bandeira de antes dopull
.git reset --hard
skip-worktree
assume-unchanged
assume-unchanged
sinalizador: o conteúdo do arquivo é revertido. O sinalizador é redefinido paraH
(deh
).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 bandeirapull
.Mas ignorar o
reset --hard
comando ' ' pode se tornar uma surpresa desagradável para um desenvolvedor.Assume-unchanged
A flag pode ser perdida napull
operação e as alterações locais dentro desses arquivos não parecem ser importantes para o git.Vejo:
O comentário de Junio (atual mantenedor do git) sobre a intenção de
assume-unchanged
,Em particular, Junio salienta que as alterações nos
assume-unchanged
arquivos podem ser acidentalmente confirmadas: "se o Git puder determinar um caminho marcado comoassume-unchanged
alterado sem incorrer em custos adicionais do lstat (2), ele se reserva o direito de informar que o caminho foi modificado ( como resultado,git commit -a
é livre para confirmar essa alteração) ".diferença entre
assume-unchanged
eskip-worktree
como discutido na lista de discussão git após a adição doskip-worktree
patch .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 )
A
git update-index
página de manual agora inclui:Essa última parte é o que descrevo um driver típico de filtro de conteúdo com base em scripts smudge / clean .
fonte