git-wad

Manage files via git but not their content
git clone git://git.meso-star.fr/git-wad.git
Log | Files | Refs | README | LICENSE

commit d8813ed141b6e7e4e7ead7ee11b4d4230dce619f
parent e3450f7af3f6505c4faaa1e6b8056873b29fbc3a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Sun, 10 Dec 2023 19:18:45 +0100

Add the checkout subcommand

Forces re-execution of the git smudge filter for WAD files, restoring
their contents.

Diffstat:
Mgit-wad | 122+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 76 insertions(+), 46 deletions(-)

diff --git a/git-wad b/git-wad @@ -37,7 +37,8 @@ fi ######################################################################## synopsis() { - >&2 printf "usage: git-wad init\n" + >&2 printf "usage: git-wad checkout\n" + >&2 printf " git-wad init\n" >&2 printf " git-wad push [--all]\n" >&2 printf " git-wad fetch [--all]\n" } @@ -60,6 +61,51 @@ encode() # digest, size printf "%s %s %d" "${GIT_WAD_HEADER}" "$1" "$2" } +wad_objects() # [--all] +{ + rev="HEAD" + + if [ $# -ge 1 ]; then + case "$1" in + "--all") rev="--all" ;; + *) + >&2 log "Invalid option %s\n" "$1" + return 1 + ;; + esac + fi + + # The following command line can be translated as follows: + # Print the IDs of all objects in "${rev}" (i.e. HEAD or --all) + # | Get their hash + # | Print object information of these hashes + # | Keep only objects that are blobs + # | Get their hash + # | Print information _and_ contents of these hashes + # | Keep only the contents of objects corresponding to WAD files + # | And finally, extract the corresponding WAD object digest + git rev-list --objects "${rev}" \ + | cut -d' ' -f1 \ + | git cat-file --batch-check \ + | grep -e "[a-z0-9]\{40\} blob [0-9]\{1,\}" \ + | cut -d' ' -f1 \ + | git cat-file --batch \ + | grep -e "^${GIT_WAD_HEADER} [0-9a-z]\{64\} [0-9]\{1,\}$" \ + | sed "s/^${GIT_WAD_HEADER} \([0-9a-z]\{64\}\) [0-9]\{1,\}$/\1/" +} + +objects_to_push() # [--all] +{ + wad_objects "$@" | xargs -I {} sh -c \ + "if [ -f \"${GIT_WAD_OBJDIR}/{}\" ]; then echo \"{}\"; fi" +} + +objects_to_fetch() # [--all] +{ + wad_objects "$@" | xargs -I {} sh -c \ + "if [ ! -f \"${GIT_WAD_OBJDIR}/{}\" ]; then echo \"{}\"; fi" +} + ######################################################################## # Git filters ######################################################################## @@ -124,51 +170,6 @@ smudge() # stdin fi } -wad_objects() # [--all] -{ - rev="HEAD" - - if [ $# -ge 1 ]; then - case "$1" in - "--all") rev="--all" ;; - *) - >&2 log "Invalid option %s\n" "$1" - return 1 - ;; - esac - fi - - # The following command line can be translated as follows: - # Print the IDs of all objects in "${rev}" (i.e. HEAD or --all) - # | Get their hash - # | Print object information of these hashes - # | Keep only objects that are blobs - # | Get their hash - # | Print information _and_ contents of these hashes - # | Keep only the contents of objects corresponding to WAD files - # | And finally, extract the corresponding WAD object digest - git rev-list --objects "${rev}" \ - | cut -d' ' -f1 \ - | git cat-file --batch-check \ - | grep -e "[a-z0-9]\{40\} blob [0-9]\{1,\}" \ - | cut -d' ' -f1 \ - | git cat-file --batch \ - | grep -e "^${GIT_WAD_HEADER} [0-9a-z]\{64\} [0-9]\{1,\}$" \ - | sed "s/^${GIT_WAD_HEADER} \([0-9a-z]\{64\}\) [0-9]\{1,\}$/\1/" -} - -objects_to_push() # [--all] -{ - wad_objects "$@" | xargs -I {} sh -c \ - "if [ -f \"${GIT_WAD_OBJDIR}/{}\" ]; then echo \"{}\"; fi" -} - -objects_to_fetch() # [--all] -{ - wad_objects "$@" | xargs -I {} sh -c \ - "if [ ! -f \"${GIT_WAD_OBJDIR}/{}\" ]; then echo \"{}\"; fi" -} - ######################################################################## # Sub commands ######################################################################## @@ -208,6 +209,34 @@ fetch() # [--all] --files-from=- "${GIT_WAD_REMOTE_FETCH}" "${GIT_WAD_OBJDIR}" } +restore() # WAD file +{ + wad="$1" + digest=$(sed "s/^${GIT_WAD_HEADER} \([0-9a-z]\{64\}\) [0-9]\{1,\}$/\1/" "${wad}") + + if [ -z "${digest}" ]; then + log "Invalid WAD file %s\n" "$1" + return 1 + fi + + if [ ! -f "${GIT_WAD_OBJDIR}"/"${digest}" ]; then + log "WAD object unavailable %s %s\n" "${digest}" "${wad}" + else + log "Restoring %s\n" "${wad}" + touch "${wad}" + git checkout-index --index --force "${wad}" + fi +} + +checkout() +{ + git ls-files \ + | xargs grep -le "^${GIT_WAD_HEADER} [0-9a-z]\{64\} [0-9]\{1,\}$" \ + | while read -r i; do + restore "${i}" + done +} + ######################################################################## # The command ######################################################################## @@ -218,6 +247,7 @@ mkdir -p "${GIT_WAD_OBJDIR}" case "${sub_cmd}" in "filter-clean") shift 1; clean "$@" ;; "filter-smudge") shift 1; smudge "$@" ;; + "checkout") shift 1; checkout "$@" ;; "init") shift 1; init "$@" ;; "fetch") shift 1; fetch "$@" ;; "push") shift 1; push "$@" ;;