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.
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.
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) .
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