As suggested by my other answer, here goes the extended, generalized, industrial-strength version of the solution.
(yes, I was bored at home and had nothing else better to do :P)
This script will add a new, detached commit based on your local design branch, so it won't affect neither the design repository or your design branch. The commit will have all desired files removed. Then it performs the merge.
For those too lazy to read the full code, the "core" of these steps can be simplified as:
original=$(gitbranch HEAD) # current branch name, or sha1 if not in a branch branchsha=$(gitsha "$branch") # sha1 of a ref, to force detached commit git checkout "$branchsha" && git rm -rf "${files[@]}" && git commit -m "$msgcommit" && newsha=$(gitsha HEAD) && git checkout "$original" && git merge -m "$msgmerge" "${mergeopts[@]}" "$newsha"
And here is the full script:
git-strip-merge
#!/bin/bash # # git-strip-merge - a git-merge that delete files on branch before merging # # Copyright (C) 2012 Rodrigo Silva (MestreLion) <[email protected]> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not see <http://www.gnu.org/licenses/gpl.html> # # Answer for "How to setup a git driver to ignore a folder on merge?" # See http://stackoverflow.com/questions/3111515 #Defaults: msgcommit="remove files from '<branch>' before merge" msgmerge="Merge stripped branch '<branch>'" verbose=0 quiet=(--quiet) usage() { cat <<- USAGE Usage: $myname [git-merge options] [-M <commitmsg>] <branch> FILE... USAGE if [[ "$1" ]] ; then cat >&2 <<- USAGE Try '$myname --help' for more information. USAGE exit 1 fi cat <<-USAGE "git-merge that delete files on "foreign" <branch> before merging Useful for ignoring a folder in <branch> before merging it with current branch. Works by deleting FILE(S) in a detached commit based on <branch>, and then performing the merge of this new commit in the current branch. Note that <branch> is not changed by this procedure. Also note that <branch> may actually be any reference, like a tag, or a remote branch, or even a commit SHA. For more information, see <http://stackoverflow.com/questions/3111515> Options: -h, --help show this page. -v, --verbose do not use -q to supress normal output of internal steps from git checkout, rm, commit. By default, only git merge output is shown. Errors, however, are never supressed -M <message>, --msgcommit=<message> message for the removal commit in <branch>. Not to be confused with the message of the merge commit, which is set by -m. Default message is: "$msgcommit" -m <message>, --message=<message> message for the merge commit. Since we are not merging <branch> directly, but rather a detached commit based on it, we forge a message similar to git's default for a branch merge. Otherwise git would use in message the full and ugly SHA1 of our commit. Default message is: "$msgmerge" For both commit messages, the token "<branch>" is replaced for the actual <branch> name. Additional options are passed unchecked to git merge. All options must precede <branch> and FILE(s), except -h and --help that may appear anywhere on the command line. Example: $myname design "photoshop/*" Copyright (C) 2012 Rodrigo Silva (MestreLion) <[email protected]> License: GPLv3 or later. See <http://www.gnu.org/licenses/gpl.html>" USAGE exit 0 } # Helper functions myname="${0##*/}" argerr() { printf "%s: %s\n" "${0##*/}" "${1:-error}" >&2 ; usage 1 ; } invalid() { argerr "invalid option: $1" ; } missing() { argerr "missing ${2:+$2 }operand${1:+ from $1}." ; } # Option handling files=() mergeopts=() for arg in "$@"; do case "$arg" in -h|--help) usage ;; esac; done while (( $# )); do case "$1" in -v|--verbose ) verbose=1 ;; -M ) shift ; msgcommit=$1 ;; -m ) shift ; msgmerge=$1 ;; --msgcommit=* ) msgcommit=${1#*=} ;; --message=* ) msgmerge=${1#*=} ;; -* ) mergeopts+=( "$1" ) ;; * ) branch="$1" shift ; break ;; esac shift done files+=( "$@" ) # Argument handling msgcommit=${msgcommit//<branch>/$branch} msgmerge=${msgmerge//<branch>/$branch} [[ "$msgcommit" ]] || missing "msgcommit" "MSG" [[ "$branch" ]] || missing "" "<branch>" (( ${#files[@]} )) || missing "" "FILE" ((verbose)) && quiet=() # Here the fun begins... gitsha() { git rev-parse "$1" ; } gitbranch() { git symbolic-ref "$1" 2> /dev/null | sed 's/refs\/heads\///' || gitsha "$1" } original=$(gitbranch HEAD) branchsha=$(gitsha "$branch") trap 'git checkout --quiet "$original"' EXIT git checkout "$branchsha" "${quiet[@]}" && git rm -rf "${files[@]}" "${quiet[@]}" && git commit -m "$msgcommit" "${quiet[@]}" && newsha=$(gitsha HEAD) && git checkout "$original" "${quiet[@]}" && git merge -m "$msgmerge" "${mergeopts[@]}" "$newsha"
Before merge:

After merge:

Note that "design" branch tip wasn't affected at all, even being a local branch, thanks to the detached commit trick. Other than that, both commits (the removal and the merge) are regular commits, with suitable commit messages and parents. And "master" branch is clean of any undesired files.