|
|
@@ -5,7 +5,7 @@
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
# You may obtain a copy of the License at
|
|
|
#
|
|
|
-# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+# https://www.apache.org/licenses/LICENSE-2.0
|
|
|
#
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
@@ -14,6 +14,12 @@
|
|
|
# limitations under the License.
|
|
|
#=============================================================================
|
|
|
|
|
|
+set -e
|
|
|
+
|
|
|
+# Disable noise from `pre-commit` when no configuration is present on the
|
|
|
+# imported tree.
|
|
|
+export PRE_COMMIT_ALLOW_NO_CONFIG=1
|
|
|
+
|
|
|
########################################################################
|
|
|
# Script for updating third party packages.
|
|
|
#
|
|
|
@@ -33,6 +39,10 @@
|
|
|
# The tag, branch or commit hash to use for upstream.
|
|
|
# shortlog
|
|
|
# Optional. Set to 'true' to get a shortlog in the commit message.
|
|
|
+# exact_tree_match
|
|
|
+# Optional. Set to 'false' to disable tree-object based matching for
|
|
|
+# previous import commit (required for projects that allow modifying
|
|
|
+# imported trees). In such cases, log-based searching is performed.
|
|
|
#
|
|
|
# Additionally, an "extract_source" function must be defined. It will be
|
|
|
# run within the checkout of the project on the requested tag. It should
|
|
|
@@ -85,7 +95,8 @@ disable_custom_gitattributes() {
|
|
|
pushd "${extractdir}/${name}-reduced"
|
|
|
# Git does not allow custom attributes in a subdirectory where we
|
|
|
# are about to merge the `.gitattributes` file, so disable them.
|
|
|
- sed -i '/^\[attr\]/ {s/^/#/;}' .gitattributes
|
|
|
+ sed -i.bak -e '/^\[attr\]/ {s/^/#/;}' .gitattributes
|
|
|
+ rm .gitattributes.bak
|
|
|
popd
|
|
|
}
|
|
|
|
|
|
@@ -95,12 +106,13 @@ die () {
|
|
|
}
|
|
|
|
|
|
warn () {
|
|
|
- echo >&2 "warning: $@"
|
|
|
+ echo >&2 "warning:" "$@"
|
|
|
}
|
|
|
|
|
|
readonly regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
|
|
|
readonly basehash_regex="$name $regex_date ([0-9a-f]*)"
|
|
|
-readonly toplevel_dir="$( git rev-parse --show-toplevel )"
|
|
|
+toplevel_dir="$( git rev-parse --show-toplevel )"
|
|
|
+readonly toplevel_dir
|
|
|
|
|
|
cd "$toplevel_dir"
|
|
|
|
|
|
@@ -117,17 +129,39 @@ cd "$toplevel_dir"
|
|
|
die "'repo' is empty"
|
|
|
[ -n "$tag" ] || \
|
|
|
die "'tag' is empty"
|
|
|
+[ -n "$exact_tree_match" ] || \
|
|
|
+ exact_tree_match=true
|
|
|
|
|
|
# Check for an empty destination directory on disk. By checking on disk and
|
|
|
# not in the repo it allows a library to be freshly re-initialized in a single
|
|
|
# commit rather than first deleting the old copy in one commit and adding the
|
|
|
# new copy in a separate commit.
|
|
|
-if [ ! -d "$(git rev-parse --show-toplevel)/$subtree" ]; then
|
|
|
- readonly basehash=""
|
|
|
+if [ ! -d "$( git rev-parse --show-toplevel )/$subtree" ]; then
|
|
|
+ basehash=""
|
|
|
+elif $exact_tree_match; then
|
|
|
+ # Find the tree object for the current subtree.
|
|
|
+ current_tree="$( git rev-parse "HEAD:$subtree" )"
|
|
|
+ # Search history for a commit whose subtree matches this tree object.
|
|
|
+ basehash=""
|
|
|
+ # Limit candidate commits to those with expected import commit messages for efficiency.
|
|
|
+ for commit in $( git rev-list --author="$ownership" --grep="$basehash_regex" HEAD ); do
|
|
|
+ imported_tree="$( git rev-parse "$commit^{tree}" )"
|
|
|
+ # Verify the imported tree is what is currently imported. If so, we
|
|
|
+ # have found the desired import commit.
|
|
|
+ if [ "$imported_tree" = "$current_tree" ] && [ -n "$imported_tree" ]; then
|
|
|
+ basehash="$commit"
|
|
|
+ break
|
|
|
+ fi
|
|
|
+ done
|
|
|
+ if [ -z "$basehash" ]; then
|
|
|
+ die "No previous import commit found with matching tree object for $subtree. (exact_tree_match enabled)"
|
|
|
+ fi
|
|
|
else
|
|
|
- readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
|
|
|
+ basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
|
|
|
fi
|
|
|
-readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p;}' | egrep '^[0-9a-f]+$' )"
|
|
|
+readonly basehash
|
|
|
+upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p;}' | grep -E '^[0-9a-f]+$' )"
|
|
|
+readonly upstream_old_short
|
|
|
|
|
|
[ -n "$basehash" ] || \
|
|
|
warn "'basehash' is empty; performing initial import"
|
|
|
@@ -142,6 +176,9 @@ readonly extractdir="$workdir/extract"
|
|
|
|
|
|
trap "rm -rf '$workdir'" EXIT
|
|
|
|
|
|
+# Skip LFS downloading; imports should not need LFS data.
|
|
|
+export GIT_LFS_SKIP_SMUDGE=1
|
|
|
+
|
|
|
# Get upstream
|
|
|
git clone --recursive "$repo" "$upstreamdir"
|
|
|
|
|
|
@@ -166,20 +203,25 @@ pushd "$upstreamdir"
|
|
|
git checkout "$tag"
|
|
|
git submodule sync --recursive
|
|
|
git submodule update --recursive --init
|
|
|
-readonly upstream_hash="$( git rev-parse HEAD )"
|
|
|
-readonly upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )"
|
|
|
-readonly upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )"
|
|
|
-readonly upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )"
|
|
|
+upstream_hash="$( git rev-parse HEAD )"
|
|
|
+readonly upstream_hash
|
|
|
+upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )"
|
|
|
+readonly upstream_hash_short
|
|
|
+upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )"
|
|
|
+readonly upstream_datetime
|
|
|
+upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )"
|
|
|
+readonly upstream_date
|
|
|
if $do_shortlog && [ -n "$basehash" ]; then
|
|
|
- readonly commit_shortlog="
|
|
|
+ commit_shortlog="
|
|
|
|
|
|
Upstream Shortlog
|
|
|
-----------------
|
|
|
|
|
|
$( git shortlog --no-merges --abbrev=8 --format='%h %s' "$upstream_old_short".."$upstream_hash" )"
|
|
|
else
|
|
|
- readonly commit_shortlog=""
|
|
|
+ commit_shortlog=""
|
|
|
fi
|
|
|
+readonly commit_shortlog
|
|
|
extract_source || \
|
|
|
die "failed to extract source"
|
|
|
popd
|
|
|
@@ -193,7 +235,7 @@ pushd "$extractdir"
|
|
|
mv -v "$name-reduced/"* .
|
|
|
rmdir "$name-reduced/"
|
|
|
git add -A .
|
|
|
-git commit -n --author="$ownership" --date="$upstream_datetime" -F - <<-EOF
|
|
|
+git commit --no-verify --no-post-rewrite --author="$ownership" --date="$upstream_datetime" -F - <<-EOF
|
|
|
$commit_summary
|
|
|
|
|
|
Code extracted from:
|
|
|
@@ -213,9 +255,9 @@ else
|
|
|
# will fail, so use the flag by default.
|
|
|
unrelated_histories_flag=""
|
|
|
if git --version | grep -q windows; then
|
|
|
- unrelated_histories_flag="--allow-unrelated-histories "
|
|
|
+ unrelated_histories_flag="--allow-unrelated-histories"
|
|
|
elif git merge --help | grep -q -e allow-unrelated-histories; then
|
|
|
- unrelated_histories_flag="--allow-unrelated-histories "
|
|
|
+ unrelated_histories_flag="--allow-unrelated-histories"
|
|
|
fi
|
|
|
readonly unrelated_histories_flag
|
|
|
|