Je veux ignorer certains fichiers d'une branche sans avoir à compter sur un fichier .gitignore
suivi qui sera écrasé lors de la fusion avec d'autres branches.
J'ai suivi de près une réponse Stack Overflow ainsi que l'article de blog lié , mais mon dépôt ne semble pas reconnaître la excludesfile
spécifiée dans mon .git/config
. La documentation Git ( git-config
, gitignore
) ne semble pas montrer comment spécifier et s’adresser un fichier d’exclusion pour une branche spécifique.
Mon .git/config
ressemble à ceci:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
excludesfile = +/info/exclude
[branch "myspecialbranch"]
excludesfile = +/info/exclude_specialbranch
Mon fichier .git/info/exclude
ressemble à ceci (par défaut, je ne le touchais pas):
# 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
Je n’ai pas de fichier .gitignore
dans mon "specialbranch".
Si j'essaie d'ignorer un fichier tel que info.php
, mon fichier .git/info/exclude_specialbranch
ressemble à ceci:
info.php
… Mais il n’ignore pas le fichier.
Si j'exécute git status --ignored
, il ne répertorie que le fichier .DS_Store
à partir du fichier par défaut exclude
.
Cependant, si j'ajoute info.php
à mon fichier .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
il ignore parfaitement le fichier.
Notez que cela fonctionne toujours sans la ligne excludesfile = +/info/exclude
sous [core]
dans .git/config
. Git semble savoir où se trouve la exclude
à l'échelle du système sans que je doive le dire.
J'ai l'impression que .git/config
ne reconnaît pas l'adresse de mon fichier personnalisé excluant le fichier:
excludesfile = +/info/exclude_specialbranch
… Probablement à cause de l'utilisation de +
pour décrire l'emplacement du répertoire .git
.
Quelle est la bonne méthode pour adresser les fichiers d’exclusion personnalisés dans les versions (les plus récentes) de Git?
J'utilise OSX 10.9.5 et Git version 2.2.1.
Vous essayez de réaliser quelque chose que Git ne supporte pas. Le blog post est la source originale de ce canular que la réponse Stack Overflow only parrote. Comme indiqué dans les commentaires sous cette réponse, même le billet de blog d'origine contient une discussion qui montre que la solution ne fonctionne pas et renvoie à un billet de blog plus récent qui indique que même l'auteur est incapable de reproduire le problème.
Pourquoi ça ne marche pas? Si vous lisez man gitignore
et man git-config
, vous trouverez juste core.excludesfile
référencé. Pas de branch.<name>.excludesfile
ici. Le core.excludesfile
est conçu pour vous permettre d'exclure, par exemple, Les fichiers .swp ou autres éléments temporaires utilisés par votre logiciel.
core.excludesfile
En plus de
.gitignore
(par répertoire) et.git/info/exclude
, Git recherche dans ce fichier des modèles de fichiers qui ne doivent pas être suivis. "~/
" est étendu à la valeur de$HOME
et "~user/
" au répertoire de base de l'utilisateur spécifié. Sa valeur par défaut est$XDG_CONFIG_HOME/git/ignore
. Si$XDG_CONFIG_HOME
est non défini ou vide, c'est plutôt$HOME/.config/git/ignore
qui est utilisé. Voir gitignore (5) .
Je crois que la meilleure approximation d'un fichier par branche exclut est obtenue en utilisant le crochet post-checkout et la réalisation du .gitignore
via un lien symbolique.
Chaque branche aurait par exemple un répertoire .gitignores
avec des fichiers nommés d'après les branches correspondantes. Ensuite, il y aurait un fichier .gitignores/__default
qui serait utilisé par défaut. Le .gitignore
serait exclu par tous les fichiers exclus et serait créé par le crochet post-paiement en tant que lien symbolique vers le fichier correspondant dans .gitignores
.
Si vous ne voulez pas suivre les fichiers exclus, vous pouvez faire de même avec le fichier .git/info/exclude
en tant que lien symbolique vers .git/info/excludes/__default
etc.
Voici un script que j'ai écrit pour faire ceci:
#!/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