commit fe8cff6f9f7d4f8a410455043d60c767861f3524
parent 29cc59b040e4530c0a28f79db6a63161be0c2184
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 18 Dec 2023 17:06:54 +0100
Fix an edge case of the "checkout" sub-command
Restoring WAD objects could fail if the "git wad checkout" command was
executed in the same second as the "git checkout" command. This could
happen when the repository was cloned by a script.
Diffstat:
| M | git-wad | | | 58 | +++++++++++++++++++++++++++++++++++++++------------------- |
1 file changed, 39 insertions(+), 19 deletions(-)
diff --git a/git-wad b/git-wad
@@ -107,6 +107,45 @@ objects_to_fetch() # [--all]
"if [ ! -f \"${GIT_WAD_OBJDIR}/{}\" ]; then echo \"{}\"; fi"
}
+# Return the current timestamp plus one second
+next_timestamp()
+{
+ awk 'BEGIN {
+ srand(); # Use the current epoch as seed
+ epoch = srand() + 1; # Return the current seed + 1, i.e. "epoch + 1"
+ print strftime("%Y-%m-%dT%H:%M:%S", epoch);
+ }'
+}
+
+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}"
+
+ # Forces re-execution of the smudge filter to restore the WAD file.
+ # Note that git caches the state of the last time the file was
+ # smudged. And there's no specific way to invalidate this cache. The
+ # easiest way seems to be to update the file's modification time by
+ # touching it. But you have to make sure that this checkout doesn't
+ # occur in the same second as the previous one. This is why we
+ # explicitly set the file's timestamp to the next timestamp, i.e.
+ # the timestamp one second in the future.
+ timestamp="$(next_timestamp)"
+ touch -d "${timestamp}" "${wad}"
+ git checkout-index --index --force "${wad}"
+ fi
+}
+
########################################################################
# Git filters
########################################################################
@@ -210,25 +249,6 @@ 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 \