Git excluifile para um branch

Eu quero ignorar certos arquivos dentro de uma ramificação sem ter que depender de um arquivo .gitignore rastreado que será sobrescrito durante a mesclagem com outras ramificações.

Eu segui de perto uma resposta do Stack Overflow junto com a postagem do blog vinculada , mas o meu repo não parece estar reconhecendo o excludesfile especificado no meu .git/config . A documentação do Git ( git-config , gitignore ) não parece mostrar como especificar e endereçar um arquivo de exclusão para uma ramificação específica.

Meu .git/config tem esta aparência:

 [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true excludesfile = +/info/exclude [branch "myspecialbranch"] excludesfile = +/info/exclude_specialbranch 

Meu arquivo .git/info/exclude tem essa aparência (por padrão, não toquei nele):

 # git ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ .DS_Store 

Eu não tenho um arquivo .gitignore no meu “specialbranch”.

Se eu tentar ignorar um arquivo como o info.php , meu arquivo .git/info/exclude_specialbranch assim:

 info.php 

… Mas não ignora o arquivo.

Se eu executar o git status --ignored , ele listará apenas o arquivo .DS_Store arquivo de exclude padrão.

No entanto, se eu adicionar info.php ao meu arquivo .git/info/exclude :

 # git ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ .DS_Store info.php 

ele ignora o arquivo perfeitamente.

Note que ele ainda funciona sem a linha excludesfile = +/info/exclude sob [core] em .git/config . Git parece saber onde a exclude todo o sistema é sem que eu tenha que dizer isso.

Tenho a sensação de que .git/config não está reconhecendo o endereço do meu arquivo de exclusões personalizado:

 excludesfile = +/info/exclude_specialbranch 

… Provavelmente por causa do uso de + para descrever a localização do diretório .git .

Qual é o método correto para endereçar arquivos de exclusão personalizados nas versões (mais recentes) do Git?

Estou executando o OSX 10.9.5 e o Git versão 2.2.1.

Git não suporta por ramo, exclui arquivos

Você está tentando conseguir algo que o Git não suporta. O post do blog é a fonte original deste embuste que o Stack Overflow responde apenas a papagaios. Como observado nos comentários sob essa resposta, até mesmo a postagem original do blog contém discussões que mostram que a solução não funciona e está vinculada a uma publicação mais recente que menciona que até mesmo o autor não consegue reproduzir o comportamento.

Por que isso não funciona? Se você ler man gitignore e man git-config , você encontrará apenas core.excludesfile referenced. Nenhuma branch..excludesfile lá. O core.excludesfile destina-se a permitir que você exclua, por exemplo, arquivos Vim .swp ou outras coisas temporárias que seu software usa.

core.excludesfile

Além de .gitignore (por diretório) e .git/info/exclude , o Git procura neste arquivo os padrões de arquivos que não devem ser rastreados. ” ~/ ” é expandido para o valor de $HOME e ” ~user/ ” para o diretório inicial do usuário especificado. Seu valor padrão é $XDG_CONFIG_HOME/git/ignore . Se $XDG_CONFIG_HOME não estiver definido ou vazio, será utilizado $HOME/.config/git/ignore . Veja gitignore (5) .

Contornar

Acredito que a melhor aproximação de um arquivo por exclusão é .gitignore por meio do hook pós-checkout e da realização do .gitignore através de um symlink.

Cada ramificação teria, por exemplo, um diretório .gitignores com arquivos nomeados após as ramificações correspondentes. Em seguida, haveria um arquivo .gitignores/__default que seria usado por padrão. O .gitignore seria excluído por todos os arquivos de exclusão e seria criado pelo gancho pós-checkout como um link simbólico para o arquivo correspondente em .gitignores .

Se você não quiser rastrear os arquivos excluídos, você pode fazer o mesmo com o arquivo .git/info/exclude como um link simbólico para .git/info/excludes/__default etc.

Aqui está um script que eu escrevi para fazer isso:

 #!/bin/bash # This is designed to allow per-branch un-ignoring of certain files. # Use case: Compiled CSS files on master to push to server. # A special .gitignore file will be present on master at # {$gitignorePath}/{$disabledMasterGitignoreName} and that file should # enable the css files using the ! flag. @https://git-scm.com/docs/gitignore # When the branch specified by script parameters # is checked out, {$gitignorePath}/{$disabledMasterGitignoreName} is # copied to .gitignore. # On other branches this gitignore file is named $disabledMasterGitignoreName, versioned, # and {$gitignorePath}.gitignore will be deleted. Note, you must ignore # {$gitignorePath}.gitignore from your main .gitignore file # # To enable put this file in your path and call this script # in .git/hooks/post-checkout with pass a list of single-space-separated branches that # will enable the branch-specific .gitignore. # One caveat is that you can only merge into the branch containing the .gitignore # file. Otherwise you'll end up re-committing the files. This is fine if you are # using gitflow and `master` contains your special .gitigore using the ! syntax # that is un-ignoring files. # # Background: @http://stackoverflow.com/questions/29579546/git-excludesfile-for-a-branch set -e gitignorePath='docroot/sites/all/themes' disabledMasterGitignoreName='.gitignore_master--disabled' #branchWithGitignoreEnabled='master' branch=$(git rev-parse --abbrev-ref HEAD) gitignoreRoot="$(git rev-parse --show-toplevel)/${gitignorePath}" if [ -f "${gitignorePath}/.gitignore" ] then masterGitignoreExists=true fi if [ -f "${gitignorePath}/${disabledMasterGitignoreName}" ] then disabledMasterGitignoreExists=true fi IFS=' ' read -a params <<< "$@" if [[ " ${params[@]} " =~ " ${branch} " ]] then if [ $disabledMasterGitignoreExists ] then cp -f "${gitignoreRoot}/${disabledMasterGitignoreName}" "${gitignoreRoot}/.gitignore" echo "Enabled ${gitignorePath}/.gitignore" fi elif [ $masterGitignoreExists ] then rm -f "${gitignorePath}/.gitignore" if [ masterGitignoreExists ] then echo "Disabled ${gitignorePath}/.gitignore" fi fi