.gitignore by branch

 

Have you ever wanted to .gitignore a file by branch?

The classic example for me here is versioning the generated styles.css file on master (which is deployed to production) but not on develop (which is used for pull requests).

Versioning the styles.css file can result in merge conflicts or PRs that are just messy.

Here's the script I wrote.

Read the comments for installation notes.

#!/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

About the Author

Hi. My name is Jeremiah John. I'm a sf/f writer and activist.

I just completed a dystopian science fiction novel. I run a website which I created that connects farms with churches, mosques, and synagogues to buy fresh vegetables directly and distribute them on a sliding scale to those in need.

In 2003, I spent six months in prison for civil disobedience while working to close the School of the Americas, converting to Christianity, as one does, while I was in the clink.