Como faço para o Git ignorar alterações no modo de arquivo (chmod)?

2311

Eu tenho um projeto no qual eu tenho que mudar o modo de arquivos com chmod para 777 durante o desenvolvimento, mas que não deve ser alterado no repositório principal.

O Git pega chmod -R 777 .e marca todos os arquivos como alterados. Existe uma maneira de fazer o Git ignorar as alterações no modo que foram feitas nos arquivos?

Marcus Westin
fonte
17
Isso é útil ao trabalhar com git no Windows + Bash no Ubuntu no Windows
Elazar
4
Para quem só quer ignorar alterações de permissão para uma invocação específica git diff, e que, portanto, não querem mudar seus arquivos de configuração do Git: você pode usar git diff -G.por Zed resposta aqui .
Sampablokuper

Respostas:

3824

Tentar:

git config core.fileMode false

No git-config (1) :

core.fileMode
    Tells Git if the executable bit of files in the working tree
    is to be honored.

    Some filesystems lose the executable bit when a file that is
    marked as executable is checked out, or checks out a
    non-executable file with executable bit on. git-clone(1)
    or git-init(1) probe the filesystem to see if it handles the 
    executable bit correctly and this variable is automatically
    set as necessary.

    A repository, however, may be on a filesystem that handles
    the filemode correctly, and this variable is set to true when
    created, but later may be made accessible from another
    environment that loses the filemode (e.g. exporting ext4
    via CIFS mount, visiting a Cygwin created repository with Git
    for Windows or Eclipse). In such a case it may be necessary
    to set this variable to false. See git-update-index(1).

    The default is true (when core.filemode is not specified
    in the config file).

O -csinalizador pode ser usado para definir esta opção para comandos únicos:

git -c core.fileMode=false diff

E o --globalsinalizador fará com que seja o comportamento padrão para o usuário conectado.

git config --global core.fileMode false

Alterações na configuração global não serão aplicadas aos repositórios existentes. Além disso, git clonee git initexplicitamente definido core.fileModecomo truena configuração do repositório, conforme discutido no Git global core.fileMode false substituído localmente no clone

Atenção

core.fileModenão é a melhor prática e deve ser usada com cuidado. Essa configuração abrange apenas o bit de modo executável e nunca os bits de leitura / gravação. Em muitos casos, você acha que precisa dessa configuração porque fez algo como chmod -R 777tornar todos os seus arquivos executáveis. Mas na maioria dos projetos, a maioria dos arquivos não precisa e não deve ser executável por motivos de segurança .

A maneira correta de resolver esse tipo de situação é manipular a permissão de pasta e arquivo separadamente, com algo como:

find . -type d -exec chmod a+rwx {} \; # Make folders traversable and read/write
find . -type f -exec chmod a+rw {} \;  # Make files read/write

Se você fizer isso, nunca precisará usar core.fileMode, exceto em ambientes muito raros.

Greg Hewgill
fonte
203
Se você o fizer, git config --global core.filemode falseprecisará fazer isso apenas uma vez para todos os repositórios.
Greg
13
Isto não funcionou para mim até que eu tenha corrigido o caso deve ser fileMode vez de fileMode
Tishma
8
@tishma: a seção de configuração do Git e os nomes das variáveis ​​não fazem distinção entre maiúsculas e minúsculas, de acordo com a documentação, consulte a seção ARQUIVO DE CONFIGURAÇÃO ; portanto, se o acima não funcionou para você, foi por um motivo diferente.
Greg Hewgill
11
@donquixote: O git configcomando grava a configuração no arquivo de configuração correto ( .git/configapenas para o repositório atual ou ~/.gitconfigse usado com --global).
Greg Hewgill
8
@ zx1986: Não importa. From git config : "Os nomes das variáveis ​​não
diferenciam
277

desfazer alteração de modo na árvore de trabalho:

git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x
git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x

Ou no mingw-git

git diff --summary | grep  'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x
git diff --summary | grep  'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x
yoda
fonte
42
No OS X Lion, omita a -d'\n'parte, xargspois esse é um argumento ilegal (e não é necessário).
Pascal
9
Você pode ignorar quaisquer erros sobre "chmod: ausente operando após` + x '"
Casey Watson
5
isso está atualizado? I get 'chmod: poucos argumentos' em mingw
hammett
7
@Pascal @pimlottc O -d especifica que o delimitador seja uma nova linha em vez de qualquer espaço em branco. O BSD xargs não tem essa opção, mas você pode canalizar a saída tr '\n' '\0'e usar o -0arg para xargs para usar NUL como delimitador.
Mark Aufflick
10
Legal, a trcoisa funcionou! Aqui está o comando completo para OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye
135

Se você deseja definir esta opção para todos os seus repositórios, use a --globalopção

git config --global core.filemode false

Se isso não funcionar, você provavelmente está usando uma versão mais recente do git, então tente a --addopção

git config --add --global core.filemode false

Se você executá-lo sem a opção --global e seu diretório de trabalho não for um repositório, você receberá

error: could not lock config file .git/config: No such file or directory
Adrien
fonte
5
Looks como usos GIT posteriores --add, como emgit config --add --global core.filemode false
mgaert
14
Se a configuração local do repositório já tiver filemode = true, a alteração da configuração global não ajudará, pois a configuração local substituirá a configuração global. Terá de mudar de configuração local de cada repo da máquina uma vez
Rakib
3
POR FAVOR: Atualize esta resposta com o aviso do syedrakib! Tudo parecia louco antes que eu o encontrasse, e fazia todo o sentido depois.
Jerclarke #
88

E se

git config --global core.filemode false

não funciona para você, faça-o manualmente:

cd into yourLovelyProject folder

cd na pasta .git:

cd .git

edite o arquivo de configuração:

nano config

alterar verdadeiro para falso

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

salve, saia, vá para a pasta superior:

cd ..

reiniciar o git

git init

você terminou!

Sinan Eldem
fonte
11
Em vez de editar .git/config, git config core.fileMode falsebasta um simples na raiz do seu projeto. Se você editar o arquivo de configuração, é melhor remover completamente a diretiva, para que a global seja escolhida.
Felix
6
-1 se git configuração --global não funcionar, significa que você não tem as permissões para fazê-lo no nível do sistema, removendo globalopção faz exatamente a mesma coisa que manualmente edição .git / config
charlesb
@CharlesB incorreto - as respostas forneceram uma solução alternativa, colocando a opção diretamente no projeto, tornando-o específico do projeto. Isso não funcionará com outros projetos git que você faz / faz checkout no futuro, mas funciona para o projeto em que está trabalhando. (vamos ter certeza disambiguate nós ~/.gitconfig, e ~/project/.git/config)
ddavison
Após a execução git init, devemos definir o modo de arquivo como true?
Jordânia
53

Adicionando à resposta de Greg Hewgill (do uso da core.fileModevariável de configuração):

Você pode usar a --chmod=(-|+)xopção de git update-index (versão de baixo nível do "git add") para alterar as permissões de execução no índice, de onde seria selecionado se você usar o "git commit" (e não o "git commit -a ").

Jakub Narębski
fonte
2
Isso deveria ter sido editado na resposta de Greg Hewgill, em vez de ser adicionado como uma resposta separada, criando assim uma resposta suprema com uma única representação inequívoca.
Greg
6
@ Greg: É preciso ter pontos suficientes para editar a resposta não própria; Eu acho que não tinha o suficiente para editar permissões naquele momento.
Jakub Narębski
1
@ Jakub Eu acho que você tem reputação suficiente agora :) Como seria esse comando para um arquivo de exemplo?
Alex Hall
38

Você pode configurá-lo globalmente:

git config --global core.filemode false

Se o exposto acima não funcionar, o motivo pode ser que sua configuração local substitua a configuração global.

Remova sua configuração local para que a configuração global entre em vigor:

git config --unset core.filemode

Como alternativa, você pode alterar sua configuração local para o valor certo:

git config core.filemode false

Tyler Long
fonte
4
Se a resposta principal não ajudar, tente esta. Se você quiser verificar a sua configuração local sem modificá-la, marque git config -l(liste a configuração atual - local e global) #
Krzysztof Bociurko
23

Se você já usou o comando chmod , verifique a diferença de arquivo. Ele mostra o modo de arquivo anterior e o modo de arquivo atual, como:

novo modo: 755

modo antigo: 644

defina o modo antigo de todos os arquivos usando o comando abaixo

sudo chmod 644 .

agora defina core.fileMode como false no arquivo de configuração usando o comando ou manualmente.

git config core.fileMode false

aplique o comando chmod para alterar as permissões de todos os arquivos, como

sudo chmod 755 .

e defina novamente core.fileMode como true.

git config core.fileMode true

Para práticas recomendadas, não mantenha o core.fileMode sempre falso.

Kishor Vitekar
fonte
Você está dizendo que um projeto inteiro (em desenvolvimento, preparação e produção) deve ser 755?
Daniel Daniel
@ Daniel Daniel: Não. Altere apenas o modo dos arquivos necessários.
Kishor Vitekar
For best practises don't Keep core.fileMode false alwaysComo assim, você deveria explicar isso.
bg17aw
For best practises don't Keep core.fileMode false always.Alguns sistemas de arquivos (FAT, por exemplo) não suportam permissões de arquivo, portanto o sistema operacional reportará um valor padrão (766 no meu sistema, de qualquer maneira). Neste caso, core.filemodeé absolutamente necessário na configuração local, a menos que queira inchar a história comprometer com alterações de permissão desnecessários e não intencionais
KevinOrr
Além disso, por que você se incomoda em alterar as permissões de volta? Se você definir core.filemode=false, o git ignorará a execução de alterações de bits, sem necessidade de alterar as permissões locais. A menos que você já tenha adicionado alterações de permissão ao índice, nesse caso, você está perdendo a etapa em que precisaria git addapós desligar core.filemode.
KevinOrr
18

Ao definir o seguinte alias (em ~ / .gitconfig), você pode facilmente desativar temporariamente o comando fileMode per git:

[alias]
nfm = "!f(){ git -c core.fileMode=false $@; };f"

Quando esse alias é prefixado para o comando git, as alterações no modo de arquivo não aparecem com comandos que, de outra forma, os mostrariam. Por exemplo:

git nfm status
Ville
fonte
14

Se você deseja definir o modo de arquivo como false nos arquivos de configuração recursivamente (incluindo submódulos): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'

dryobs
fonte
4
Isso não funcionará se essa linha não estiver no arquivo de configuração. Se você quiser alterá-lo para submódulos, tente o seguinte:git submodule foreach git config core.fileMode false
courtlandj
4

Solução simples:

Pressione este comando Simples na pasta do projeto ( não removerá as alterações originais) ... ele removerá apenas as alterações que foram feitas enquanto você alterava a permissão da pasta do projeto

O comando está abaixo:

git config core.fileMode false

Por que esse arquivo desnecessário é modificado: porque você alterou as permissões da pasta do projeto com o comando sudo chmod -R 777 ./yourProjectFolder

quando você verificará as alterações, o que você não fez? você encontrou abaixo enquanto usava o nome do arquivo git diff

old mode 100644
new mode 100755
Shashwat Gupta
fonte
1

Isso funciona para mim:

find . -type f -exec chmod a-x {} \;

ou reverter, dependendo do seu sistema operacional

find . -type f -exec chmod a+x {} \;
Martin Volek
fonte
1
Isso mudaria as permissões do arquivo, mas não faria o git ignorar as permissões do arquivo.
domdambrogia 11/01/19
Bem, você está certo, isso não resolve a coisa do git ignore.
Martin Volek