commit a24f7aad32dd629200eb5358ad4c19d45e086c27
parent 0c8a1c5701be1a9d1f7cea90e82b271169c9b9a8
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Sun, 14 Jan 2024 18:29:25 +0100
Add the status subcommand
It displays all the relevant information on WAD management to help the
user understand the current state of his work tree and what he can do
about it. It warns if git-wad is not initialized for the current
repository. It also indicates the number of WAD objects that can be
pruned. Finally, it lists WAD files according to their status, i.e.
resolved, data orphaned or not restored. To further assist the user, we
follow the git tradition by giving useful git-wad commands in relation
to the displayed statuses.
Diffstat:
| M | git-wad | | | 114 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
1 file changed, 112 insertions(+), 2 deletions(-)
diff --git a/git-wad b/git-wad
@@ -43,6 +43,13 @@ synopsis()
>&2 printf " git-wad prune [--all]\n"
>&2 printf " git-wad pull [--all]\n"
>&2 printf " git-wad push [--all]\n"
+ >&2 printf " git-wad status [--all]\n"
+}
+
+is_init()
+{
+ git config --get filter.wad.clean > /dev/null \
+ && git config --get filter.wad.smudge > /dev/null
}
log() # str [, arg...]
@@ -244,8 +251,8 @@ smudge() # stdin
# Setup git filters
init()
{
- if git config --get filter.wad.clean > /dev/null \
- && git config --get filter.wad.smudge > /dev/null; then
+ # shellcheck disable=SC2310
+ if is_init; then
log "git-wad is already initialized (check .git/config)\n"
else
git config filter.wad.clean "git-wad filter-clean"
@@ -308,6 +315,108 @@ prune() # [--all]
rm -f \"${GIT_WAD_OBJDIR}/{}\""
}
+# Print WAD management status
+status() # [--all]
+{
+ # Create 3 temp files to list resolved, unrestored and orphaned WADs
+ resolved="$(mktemp -p "${GIT_WAD_OBJDIR}")"
+ unrestored="$(mktemp -p "${GIT_WAD_OBJDIR}")"
+ orphaned="$(mktemp -p "${GIT_WAD_OBJDIR}")"
+
+ # The following command line can be translated as follows:
+ # Print the IDs of all objects in HEAD
+ # | Get their hash
+ # | Print object information of these hashes
+ # | Keep only objects that are blobs
+ # | Get their hash
+ # | And loop over them
+ git rev-list --objects HEAD \
+ | cut -d' ' -f1 \
+ | git cat-file --batch-check \
+ | grep -e "[a-z0-9]\{40\} blob [0-9]\{1,\}" \
+ | cut -d' ' -f1 \
+ | while read -r hash; do
+
+ # Test if the object is a WAD
+ is_wad="$(git cat-file blob "${hash}" \
+ | sed -n "/^${GIT_WAD_HEADER} [0-9a-z]\{64\} [0-9]\{1,\}$/{p;q}")"
+ [ -z "${is_wad}" ] && continue
+
+ # From here on, the current hash refers to a WAD
+
+ # Find the file name of the WAD in the current working tree
+ wad="$(git ls-tree -r --format="%(objectname) %(path)" HEAD "${working_tree}" \
+ | grep -e "^${hash} " \
+ | cut -d' ' -f2)"
+
+ # Read the WAD bytes corresponding to its header before it is restored
+ header_size="$(sizeof_header)"
+ header="$(dd if="${wad}" ibs=1 count="${header_size}" 2> /dev/null)"
+
+ # The header read is not a valid WAD header, i.e. the WAD has
+ # already been restored
+ if [ "${header}" != "${GIT_WAD_HEADER}" ]; then
+ printf "%s\n" "${wad}" >> "${resolved}"
+
+ else
+ # Read the WAD digest from its header
+ digest=$(sed \
+ -e "1s/^${GIT_WAD_HEADER} \([0-9a-z]\{64\}\) [0-9]\{1,\}$/\1/" \
+ "${wad}")
+
+ # Check whether a file corresponding to the WAD digest exists
+ # locally. If so, the WAD file is simply not restored. Otherwise,
+ # it is orphaned of its data.
+ if [ -f "${GIT_WAD_OBJDIR}/${digest}" ]; then
+ printf "%s\n" "${wad}" >> "${unrestored}"
+ else
+ printf "%s\n" "${wad}" >> "${orphaned}"
+ fi
+ fi
+ done
+
+ # shellcheck disable=SC2310
+ if ! is_init; then
+ printf "\e[0;31mgit-wad is not initialized\e[0m\n"
+ printf " (use \"git wad init\" to enable WAD management)\n"
+ printf "\n"
+ fi
+
+ # List resolved WADs, if any
+ n="$(wc -l < "${resolved}")"
+ if [ "${n}" -gt 0 ]; then
+ printf "Resolved WADs:\n"
+ xargs -I{} printf "\t\e[0;32m%s\e[0m\n" {} < "${resolved}"
+ printf "\n"
+ fi
+
+ # List un-restored WADs, if any
+ n="$(wc -l < "${unrestored}")"
+ if [ "${n}" -gt 0 ]; then
+ printf "Unrestored WADs:\n"
+ printf " (use \"git wad checkout\" to restore WADs)\n"
+ xargs -I {} printf "\t\e[0;33m%s\e[0m\n" {} < "${unrestored}"
+ printf "\n"
+ fi
+
+ # List orphaned WADs, if any
+ n="$(wc -l < "${orphaned}")"
+ if [ "${n}" -gt 0 ]; then
+ printf "Orphaned WADs:\n"
+ printf " (use \"git wad pull\" to download and restore WADs)\n"
+ xargs -I {} printf "\t\e[0;31m%s\e[0m\n" {} < "${orphaned}"
+ printf "\n"
+ fi
+
+ # Print number of WADs not referenced in current work tree
+ n="$(unreferenced_objects | wc -l)"
+ if [ "${n}" -gt 0 ]; then
+ printf "There are %d WADs not use in the current working tree\n" "${n}"
+ printf " (use \"git wad prune\" to remove them)\n"
+ fi
+
+ rm -f "${resolved}" "${orphaned}" "${unrestored}"
+}
########################################################################
# The command
@@ -325,5 +434,6 @@ case "${sub_cmd}" in
"prune") shift 1; prune "$@" ;;
"push") shift 1; push "$@" ;;
"pull") shift 1; pull "$@" ;;
+ "status") shift 1; status "$@" ;;
*) synopsis; exit 1 ;;
esac