chiark / gitweb /
dgit: absurd: Work around mangled env metadata from gbp
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 1 Feb 2020 21:12:25 +0000 (21:12 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 2 Feb 2020 16:31:51 +0000 (16:31 +0000)
Some versions of gbp pq will pass broken metadata from patch files
into the env vars for git-commit-tree.  Eg, #950446/#950326 where gbp
pq from buster cannot cope with binutils_2.33.90.20200122-2.dsc,
setting GIT_AUTHOR_DATE to "???" (literally, three ? marks, as copied
from the patch file libctf-soname.diff).

Work around this as follows:
 * Try git-commit-tree of an empty commit message.  Does it work?
   If so, workaround is not needed.
 * Try resetting GIT_AUTHOR_* to GIT_COMMITTER_*.  Does it work now?
   Ah, that is the fix!
 * Otherwise, just run git-commit-tree as usual.

This code makes some perhaps-unreasonable assumptions:
 * gbp's git commit-tree has the tree object as 2nd argument
   (really shonky command line parsing).  However, if this
   assumption is violated, the result is that the git-commit-tree
   attempts either fail harmlessly, or succeed harmlessly, defeating
   the workaround but with no other implications.
 * if a workaround is needed, it is best to throw away all the
   author information, rather that try to pick and choose, or to
   fix it up.
These are IMO tolerable because I think it's gbp's job to get this
right.  The output from dgit (if it succeeds) will be right in terms
of tree and even in terms of commit structure.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
absurd/git

index d8ac24e..d9e2d4e 100755 (executable)
@@ -29,10 +29,35 @@ filter_path () {
        PATH=$npath
 }
 
+squash_author () {
+       author_vars='NAME EMAIL DATE'
+       for var in in $author_vars; do
+               eval "GIT_AUTHOR_$var=\$GIT_COMMITTER_$var"
+       done
+}
+
+try_commit () { git commit-tree "$try_commit_obj" </dev/null >/dev/null; }
+
+maybe_squash_author () {
+       if   (set -e; filter_path;                try_commit); then return; fi
+       if ! (set -e; filter_path; squash_author; try_commit); then return; fi
+       read last <../../absurd-apply-applied
+       echo >&4 \
+ "dgit: warning: suppressed corrupted metadata! ($last)"
+       squash_author
+}
+
 bypass=true
 for arg in "$@"; do
        case "$arg" in
        apply)  bypass=false; break     ;;
+       commit-tree)
+               # Work around #950446 in gbp
+               echo >&3 "DGIT ABSURD GIT APPLY - COMMIT-TREE: $*"
+               try_commit_obj="$2"
+               maybe_squash_author
+               bypass=true; break
+               ;;
        -*)                             ;;
        *)      bypass=true; break      ;;
        esac
@@ -118,4 +143,5 @@ git checkout debian/patches/series
 git add -Af .
 
 log "APPLIED $patch"
+printf >../../absurd-apply-applied '%s\n' "$patch"
 #printf 'APPLIED '; date --iso-8601=ns