diff --git a/package/pkg-download.mk b/package/pkg-download.mk index 30eeb6b1fc..9047e99f86 100644 --- a/package/pkg-download.mk +++ b/package/pkg-download.mk @@ -20,7 +20,7 @@ export LOCALFILES := $(call qstrip,$(BR2_LOCALFILES)) # Version of the format of the archives we generate in the corresponding # download backend: -BR_FMT_VERSION_git = -br1 +BR_FMT_VERSION_git = -br2 BR_FMT_VERSION_svn = -br3 DL_WRAPPER = support/download/dl-wrapper diff --git a/support/download/git b/support/download/git index 6654d98a00..8134c07214 100755 --- a/support/download/git +++ b/support/download/git @@ -226,6 +226,66 @@ if [ ${large_file} -eq 1 ]; then fi fi +# Find files that are affected by the export-subst git-attribute. +# There might be a .gitattribute at the root of the repository, as well +# as in any arbitrary sub-directory, whether from the master repository +# or a submodule. +# "git check-attr -z" outputs results using \0 as separator for everything, +# so there is no difference between field or records (but there is a +# trailing \0): +# path_1\0attr_name\0attr_state\0path_2\0attr_name\0attr_state\0.... +mapfile -d "" files < <( + set -o pipefail # Constrained to this sub-shell + find . -print0 \ + |_plain_git check-attr --stdin -z export-subst \ + |(i=0 + while read -r -d "" val; do + case "$((i++%3))" in + (0) path="${val}";; + (1) ;; # Attribute name, always "export-subst", as requested + (2) + if [ "${val}" = "set" ]; then + printf "%s\0" "${path}" + fi;; + esac + done + ) +) +# Replace format hints in those files. Always use the master repository +# as the source of the git metadata, even for files found in submodules +# as this is the most practical: there is no way to chdir() in (g)awk, +# and recomputing GIT_DIR for each submodule would really be tedious... +# There might be any arbitrary number of hints on each line, so iterate +# over those one by one. +for f in "${files[@]}"; do + TZ=UTC \ + LC_ALL=C \ + GIT_DIR="${git_cache}/.git" \ + awk -v GIT="${GIT}" ' + { + l = $(0); + while( (i = match(l, /\$Format:[^\$]+\$/)) > 0 ) { + len = RLENGTH; + printf("%s", substr(l, 1, i-1) ); + fmt = substr(l, i, RLENGTH); + pretty = substr(fmt, 9, length(fmt)-9); + cmd = GIT " -c core.abbrev=40 log -s -n1 --pretty=format:'\''" pretty "'\''"; + while ( (cmd | getline replace) > 0) { + printf("%s", replace); + } + ret = close(cmd); + if (ret != 0) { + printf("%s:%d: error while executing command \"%s\"\n", FILENAME, NR, cmd) > "/dev/stderr"; + exit 1; + } + l = substr(l, i+len); + } + printf("%s\n", l); + } + ' "${f}" >"${f}.br-temp" + mv -f "${f}.br-temp" "${f}" +done + popd >/dev/null # Generate the archive.