Git excludesfile for a branch

前端 未结 2 1616
一个人的身影
一个人的身影 2020-11-28 09:47

I want to ignore certain files within a branch without having to rely on a tracked .gitignore file that will be overwritten during merges with other branches.

相关标签:
2条回答
  • 2020-11-28 09:57

    Here's a script I wrote to do this:

    #!/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
    
    0 讨论(0)
  • 2020-11-28 09:59

    Git does not support per-branch excludes files

    You’re trying to achieve something that Git does not support. The blog post is the original source of this hoax that the Stack Overflow answer only parroted. As noted in comments under that answer, even the original blog post contains discussion that brings out that the solution does not work and it links to a newer blog post that mentions that even the author is unable to reproduce the behavior.

    Why it does not work? If you read man gitignore and man git-config, you’ll find just core.excludesfile referenced. No branch.<name>.excludesfile there. The core.excludesfile is meant to enable you to exclude e.g. Vim .swp files or other temporary stuff your software uses.

    core.excludesfile

    In addition to .gitignore (per-directory) and .git/info/exclude, Git looks into this file for patterns of files which are not meant to be tracked. "~/" is expanded to the value of $HOME and "~user/" to the specified user’s home directory. Its default value is $XDG_CONFIG_HOME/git/ignore. If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore is used instead. See gitignore(5).

    Work-around

    I believe that the best approximation of a per-branch excludes file is achieved using the post-checkout hook and realization of the .gitignore via a symlink.

    Each branch would have e.g. a .gitignores directory with files named after the corresponding branches. Then there would be a .gitignores/__default file that would be used by default. The .gitignore would be excluded by all the excludes files and would be created by the post-checkout hook as a symlink to the corresponding file in .gitignores.

    If you don’t want to track the excludes files, you may do the same with .git/info/exclude file as a symlink to .git/info/excludes/__default etc.

    0 讨论(0)
提交回复
热议问题