2015-04-11 18 views
13

Voglio ignorare determinati file all'interno di un ramo senza dover fare affidamento su un file tracciato .gitignore che verrà sovrascritto durante l'unione con altri rami.Esclusione file per un ramo

Ho seguito da vicino a Stack Overflow answer con the linked blog post, ma il mio repo non sembra essere il riconoscimento del specificato excludesfile nel mio .git/config. La documentazione Git (git-config, gitignore) non sembra mostrare come specificare e indirizzare un file di esclusione per un ramo specifico.

mio .git/config assomiglia a questo:

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

[branch "myspecialbranch"] 
     excludesfile = +/info/exclude_specialbranch 

Il mio file .git/info/exclude assomiglia a questo (per impostazione predefinita, non ho toccarlo):

# 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 

non ho un file .gitignore nel mio "specialbranch".

Se cerco di ignorare un file, come info.php, il mio file .git/info/exclude_specialbranch assomiglia a questo:

info.php 

... ma non ignora il file.

Se corro git status --ignored, elenca solo il file .DS_Store dal file exclude predefinito.

Tuttavia, se aggiungo info.php al mio file .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 

ignora il file perfettamente.

Si noti che funziona ancora senza la linea excludesfile = +/info/exclude in [core] in .git/config. Git sembra sapere dov'è il sistema exclude senza che io debba dirlo.

Ho la sensazione che .git/config non riconosce l'indirizzo del mio costume esclude di file:

excludesfile = +/info/exclude_specialbranch 

... molto probabilmente a causa dell'uso di + per descrivere il percorso della directory .git.

Qual è il metodo corretto per indirizzare i file di esclusione personalizzati nelle versioni (più recenti) di Git?

Sono in esecuzione OSX 10.9.5 e Git versione 2.2.1.

risposta

20

Git non supporta esclude per-branch file

Stai cercando di realizzare qualcosa che Git non supporta. Il blog post è la fonte originale di questa bufala che solo il pappagallo è stato copiato da the Stack Overflow answer. Come notato nei commenti sotto quella risposta, anche il post originale del blog contiene una discussione che fa emergere che la soluzione non funziona e si collega a uno newer blog post che menziona che anche l'autore non è in grado di riprodurre il comportamento.

Perché non funziona?Se leggi man gitignore e man git-config, troverai solo il riferimento core.excludesfile. No branch.<name>.excludesfile lì. Lo core.excludesfile ha lo scopo di consentire all'utente di escludere, ad es. File Vim .swp o altre cose temporanee utilizzate dal software.

core.excludesfile

Oltre a .gitignore (per directory) e .git/info/exclude, Git guarda in questo file per i modelli di file che non sono destinate ad essere monitorati. "~/" viene esteso al valore di $HOME e "~user/" alla directory home dell'utente specificato. Il suo valore predefinito è $XDG_CONFIG_HOME/git/ignore. Se $XDG_CONFIG_HOME non è impostato o vuoto, viene utilizzato invece $HOME/.config/git/ignore. Vedi gitignore(5).

work-around

credo che la migliore approssimazione di un file esclude per-ramo si ottiene utilizzando la realizzazione del .gitignorepost-checkout hook e tramite un link simbolico.

Ogni ramo avrebbe ad es. una directory .gitignores con file denominati in corrispondenza dei rami corrispondenti. Quindi ci sarebbe un file .gitignores/__default che verrebbe usato di default. Lo .gitignore verrebbe escluso da tutti i file esclusi e verrebbe creato dal hook post-checkout come collegamento simbolico al file corrispondente in .gitignores.

Se non si desidera tenere traccia dei file esclude, si può fare lo stesso con .git/info/exclude file come link simbolico a .git/info/excludes/__default ecc

+0

Se vuoi maggiori informazioni sul work-around, sentiti libero di mandarmi un ping tramite @Palec nei commenti qui. – Palec

+0

ha grazie - ho appena finito di leggere l'intero http://git-scm.com/docs/git-config (!) E mi chiedevo perché non ho visto un branch.excludesfile - controllerò il tuo lavoro- in giro. – goredwards

+0

Ho controllato la cronologia delle pagine man di git-config e gitignore e non hanno mai menzionato 'branch. .excludesfile'. – Palec

1

Ecco uno script che ho scritto per fare questo:

#!/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 <<< "[email protected]" 

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