Skip to content

Instantly share code, notes, and snippets.

@garthk
Created June 6, 2025 06:59
Show Gist options
  • Save garthk/fee161d8460a5f4c34f34cae0054cfc5 to your computer and use it in GitHub Desktop.
Save garthk/fee161d8460a5f4c34f34cae0054cfc5 to your computer and use it in GitHub Desktop.
Tell macOS' Time Machine to ignore the files Git ignores
#!/bin/bash
# shellcheck enable=all disable=SC2030,SC2249,SC2250
function git-tmutil-ignore() (
set -euo pipefail
case $=${ZSH_NAME-${BASH-other}} in
*/bash) shopt -s lastpipe ;;
esac
attr_name=com.apple.metadata:com_apple_backup_excludeItem
attr_value=bplist00_com.apple.backupd
function init-for() {
last=''
header=${1?need HEADER}
}
function print-item() {
if [[ -n $header ]]; then
echo >&2 "$header"
header=''
fi
echo >&2 "- ${1?need ITEM}"
printf '%s\0' "${repo?}/$1"
}
function directories-to-reset() (
init-for "Resetting tracked directories in $repo..."
local last='////'
while IFS= read -r line; do
case $line in
"$last"/*) continue ;; # skip last dir's contents
*/*) last=${line//\/*/} && print-item "$last" ;; # print top-most parent dir
esac
done
)
function directories-to-exclude() (
init-for "Excluding ignored directories in $repo..."
local last='////'
while IFS= read -r line; do
case $line in
"$last"/*) continue ;; # skip last dir's contents
*/) last=${line/%\//} && print-item "$last" ;; # print dirs
esac
done
)
(($#)) || set -- "$PWD"
while (($#)); do
repo=$1
shift
LC_ALL=C git -C "$repo" ls-files --cached |
directories-to-reset |
xargs -r0 xattr -rd "$attr_name"
LC_ALL=C git -C "$repo" ls-files --others --directory --ignored --exclude-standard --deduplicate |
directories-to-exclude |
xargs -r0 xattr -w "$attr_name" "$attr_value"
done
)
if ! (return 0 2> /dev/null); then
git-tmutil-ignore "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment