1#!/bin/sh 2 3# some git commands print to stdout, which would contaminate our JSON output 4clean_git(){ 5 git "$@" >&2 6} 7 8# Remove all remote branches, remove tags not reachable from HEAD, do a full 9# repack and then garbage collect unreferenced objects. 10make_deterministic_repo(){ 11 local repo="$1" 12 13 # run in sub-shell to not touch current working directory 14 ( 15 cd "$repo" 16 # Remove files that contain timestamps or otherwise have non-deterministic 17 # properties. 18 rm -rf .git/logs/ .git/hooks/ .git/index .git/FETCH_HEAD .git/ORIG_HEAD \ 19 .git/refs/remotes/origin/HEAD .git/config 20 21 # Remove all remote branches. 22 git branch -r | while read -r branch; do 23 clean_git branch -rD "$branch" 24 done 25 26 # Remove tags not reachable from HEAD. If we're exactly on a tag, don't 27 # delete it. 28 maybe_tag=$(git tag --points-at HEAD) 29 git tag --contains HEAD | while read -r tag; do 30 if [ "$tag" != "$maybe_tag" ]; then 31 clean_git tag -d "$tag" 32 fi 33 done 34 35 # Do a full repack. Must run single-threaded, or else we lose determinism. 36 clean_git config pack.threads 1 37 clean_git repack -A -d -f 38 rm -f .git/config 39 40 # Garbage collect unreferenced objects. 41 # Note: --keep-largest-pack prevents non-deterministic ordering of packs 42 # listed in .git/objects/info/packs by only using a single pack 43 clean_git gc --prune=all --keep-largest-pack 44 ) 45}