#!/bin/bash # usage: gitar foo-dir >foo.gitar set -e trap 'echo "Unexpected error! I am leaving the .git subdirectory around so you can troubleshoot; delete the subdirectory before trying to gitar again." 1>&2' ERR cd "$1" if [ -e '.git' ]; then echo 'The source directory is already a git repository!' 1>&2 exit 1 fi if ! find . -type d -empty | cmp /dev/null - >/dev/null; then echo 'WARNING: The source directory contains empty directories, and git will drop them.' 1>&2 fi # Make repository. git init-db >/dev/null # Make a dummy commit to hold all the files. function list-files-to-add { find . -wholename './.git' -prune -or '(' -type f -or -type l ')' -printf '%P\n' } list-files-to-add | git update-index --add --stdin >/dev/null tree=$(git write-tree) function clean-commit { GIT_AUTHOR_NAME='reproducible' GIT_AUTHOR_EMAIL='' GIT_AUTHOR_DATE='946684801 +0000' GIT_COMMITTER_NAME='reproducible' GIT_COMMITTER_EMAIL='' GIT_COMMITTER_DATE='946684801 +0000' git commit-tree "$@" .git/refs/heads/master # Pack things up nicely. git repack -a >/dev/null for i in pack idx; do mv .git/objects/pack/{pack*.$i,pack.$i} done git prune >/dev/null # Write out git repository as a Matt-style file tree. function write_file { echo -n "+ ${#2} $2 " stat --format=$'f %s' -- "$1/$2" cat -- "$1/$2" echo } echo '{' echo '+ 4 HEAD f 23' echo 'ref: refs/heads/master' echo echo '+ 4 refs {' echo '+ 5 heads {' write_file .git/refs/heads master echo '}' echo '}' echo '+ 7 objects {' echo '+ 4 pack {' write_file .git/objects/pack pack.pack write_file .git/objects/pack pack.idx echo '}' echo '}' echo '}' rm -rf .git